[erlang-questions] gen_server aggregating calls/casts
Jonathan Leivent
jleivent@REDACTED
Tue Jul 9 19:23:34 CEST 2013
On 07/08/2013 07:27 PM, Robert Raschke wrote:
> Have you considered using a queuing framework, like RabbitMQ?
What I'm trying to implement is too low level to make use of RabbitMQ.
Ideally, if this works, it would be used within such frameworks.
> ...
>
> Alternatively, you'll probably want to double layer your server, as was
> previously suggested.
I think that will eventually be my best option - especially as I just
learned that Erlang does no inter-node flow control on its own. So, the
outer layer will have to both aggregate requests AND flow control them
as well, as there may be a very large number of requests coming from a
very large number of clients.
It's surprising to me that Erlang provides no built-in flow control,
since it is using TCP. A gen_server that just receives and aggregates
messages on a list could end up using a lot of memory with no way to
push back.
My gen_server can actually tolerate having incoming requests dropped
more than it can tolerate having aggregation use up lots of memory
(potentially dying if it runs out, or at least slowing things down).
Maybe that means I will need to use gen_UDP - I knew I would eventually
switch to UDP to bypass the TCP overhead, but now that looks like a
sooner-rather-than-later project.
For now, I cheated and used gen_server's internal message format - just
because doing that turns out to perturb the code I already have the
least. All it takes is:
aggregate_requests(L) ->
receive
{'$gen_call', From, R={request, _}} ->
aggregate_requests([{From, R}|L])
after 0 -> L
end.
That's just too tidy and easy to pass up, even if it does break
modularity. I know I'll have to replace this when I face the
flow-control issue.
-- Jonathan
More information about the erlang-questions
mailing list