[erlang-questions] Architecture: How to achieve concurrency when gen_server:handle_call waits?
Sun Feb 7 14:37:50 CET 2016
You're thinking in traditional non-Erlang ideas of concurrency. Have X processes handling Y clients where X << Y. The Erlang way is to have X processes handling X clients. Each client gets its own process. This is how cowboy/yaws achieve concurrency.
Of course not every problem falls into such an architecture. Then you deal with it as the situation demands. Also using gen_server:call for everything is not a good design choice. it should only be used when it's actually needed. Very often gen_server:cast is the right choice.
> On 07 Feb 2016, at 14:20, Luke <> wrote:
> The way I'm getting my head around the actor model & OTP is to imagine it's like an office building full of people with specialised jobs (gen_servers), and you send emails to people who work on your request right away and reply when they're done (for a handle_call). If I have used call then it's as if I fire off the email and sit there clicking refresh until I get a reply (or like a literal call, I am on hold until they get back to me), but if I use cast then I just get on with my day and maybe check my inbox again later. I can see a lot of benefits with this kind of organisation of your programs and like it a lot.
> My problem is that when a gen_server is working on something they are busy and can't answer more calls/casts. Is the correct way to achieve concurrency in Erlang to have each gen_server spawn a brand new process and then go back to checking their inbox again? In the office building metaphor, essentially each worker also has access to an infinite pool of interns and they are able to forward tasks, immediately delegating all the work away (I used to work at Ericsson, I can see how this model comes naturally to them :P)
> If this is indeed the correct way to achieve concurrency, I still have the following questions:
> 1 - Why isn't this done automatically behind the scenes in gen_server? When would you ever not want to free up your gen_server to handle more requests?
> 2 - Is it best practice to spawn each new process under the gen_server, a supervisor somewhere, or not all?
> 3 - If your gen_server is being flooded with messages, would one viable solution to achieve concurrency be creating say 10 of the same gen_server under a supervisor, and having any processes passing messages to this "job" randomly pick one, effectively using probability to reduce traffic to each by 1/10 - is there a library/methodology for doing this kind of thing already?
> 4 - This seems like it would be a common piece of code, is this bundled into OTP somewhere? Is this situation what I'm supposed to use gen_event for? Or if I'm completely wrong, what is the actual way programs like yaws achieve high concurrency, as reading the source code has not revealed the answer to me.
> erlang-questions mailing list
More information about the erlang-questions