[erlang-questions] time consuming operations inside gen_server

Loïc Hoguin essen@REDACTED
Wed Dec 12 11:30:05 CET 2012

Workers shouldn't be gen_servers. If they are, they are quite poor ones 
considering you'll have a hard time inspecting it, debugging it or 
tracing it because your sys:get_status/1 call will simply timeout while 
the gen_server is busy doing whatever it's doing. You also likely have a 
single call/cast for it, so you don't use much of gen_server itself.

It's OK to write processes that aren't gen_servers, especially in cases 
like this. All you have to do is spawn a supervised worker passing it 
your Pid, monitor it and then wait for either it to go down or finish 
the task and give a result which you'll get back as a message. The 
worker can simply stop after it sends said message. If you don't expect 
a result, it's even simpler!

On 12/12/2012 11:04 AM, Max Bourinov wrote:
> Hi Martin,
> First of all I try to avoid calls in my systems. I believe that is there
> is a call - there is a potential lock. Casts are friends.
> In your case I would suggest you to have "special" workers for time
> consuming operations. Workers should be gen_servers and should be a part
> of your supervisors tree.
> This is just a general suggestion - of course each case is unique.
> Please adapt it to your case if possible.
> Best regards,
> Max
> On Wed, Dec 12, 2012 at 1:46 PM, Martin Dimitrov <mrtndimitrov@REDACTED
> <mailto:mrtndimitrov@REDACTED>> wrote:
>     Thanks, this sounds very cool.
>     On 12/12/2012 11:42 AM, Attila Rajmund Nohl wrote:
>      > 2012/12/12 Martin Dimitrov <mrtndimitrov@REDACTED
>     <mailto:mrtndimitrov@REDACTED>>:
>      >> Hi all,
>      >>
>      >> In our application, we have a gen_server that does a time consuming
>      >> operation. The message is of type cast thus the caller process
>     doesn't
>      >> sit and wait for the operation to finish. But while the
>     gen_server is
>      >> busy with the cast message, it doesn't serve any other call, right?
>      >>
>      >> So, would it be appropriate to create a process that will do the
>     time
>      >> consuming operation and then notify the gen_server?
>      >
>      > The pattern I use in this case is to still use gen_server:call
>     (if the
>      > caller needs to be blocked), start a separate process for the
>      > time-consuming stuff, return {noreply, ...} from the handle_call (so
>      > the gen_server can handle other calls), then call gen_server:reply
>      > from the started process when the time-consuming operation finished.
>      > Of course, the applicability of this pattern depends on what you
>      > actually do.
>      >
>     _______________________________________________
>     erlang-questions mailing list
>     erlang-questions@REDACTED <mailto:erlang-questions@REDACTED>
>     http://erlang.org/mailman/listinfo/erlang-questions
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

Loïc Hoguin
Erlang Cowboy
Nine Nines

More information about the erlang-questions mailing list