queue process with capacity

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

queue process with capacity

semmit mondo-2
Hi,
 
I need to implement a queue service that has a capacity.  This means that the `in` actions has to be able to block the producer when the queue is full, and also the `out` action has to be able to block the consumer when the queue is empty.
 
Sending in an item and then receiving with "after infinity" in the producer seems to be a working approach.  But my concern is that this way the producer process is blocked and so it is unable to respond to any system messages.  If I do this in a supervised process, do I break the contract between OTP and that process?  Aren't all the processes supposed to answer certain low level messages that is handled by gen_server without me to even know about?  Shouldn't supervised processes be blocked only in the gen_server's main receive loop?
 
I feel that receiving indefinitely is something I should avoid.  But how can I implement the queue in an OTP friendly way?
 
S.
 

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: queue process with capacity

Dmitry Kolesnikov-2
Hello,

There are multiple Erlang project that provides necessary queuing features. You can google them with “erlang simple queue”

The gen_server callback supplies you a From entity. This is a “channel” to acknowledge request processing. You queue this entity internally and uses gen_server:reply(…) to acknowledge consumer/producer when it’s request is completed.  
```
Module:handle_call(Request, From, State) -> Result

http://erldocs.com/19.0/stdlib/gen_server.html?i=13&search=gen_server#reply/2
http://erldocs.com/19.0/stdlib/gen_server.html?i=4&search=gen_server#call/3
```

Here is a sketch of the code
```
handle_call(dequeue, From, #state{q = Q} = State) ->
  {noreply, State#state{q = queue:in(From, Q)}};

handle_call({enqueue, X}, _, #state{q = Q} = State) ->
   gen_server:reply(queue:head(Q), X),
   ...
```

I hope you got an implementation idea.
Please let me know if more info is needed

Best Regards,
Dmitry Kolesnikov | Digital Cossack
[hidden email]



> On Mar 2, 2017, at 4:44 PM, semmit mondo <[hidden email]> wrote:
>
> Hi,
>  
> I need to implement a queue service that has a capacity.  This means that the `in` actions has to be able to block the producer when the queue is full, and also the `out` action has to be able to block the consumer when the queue is empty.
>  
> Sending in an item and then receiving with "after infinity" in the producer seems to be a working approach.  But my concern is that this way the producer process is blocked and so it is unable to respond to any system messages.  If I do this in a supervised process, do I break the contract between OTP and that process?  Aren't all the processes supposed to answer certain low level messages that is handled by gen_server without me to even know about?  Shouldn't supervised processes be blocked only in the gen_server's main receive loop?
>  
> I feel that receiving indefinitely is something I should avoid.  But how can I implement the queue in an OTP friendly way?
>  
> S.
>  
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Loading...