I'm not sure about this. It would make Elixir's GenServer different from 
Erlang's gen_server, and I'm not sure that's ok. I agree that it's nasty to 
do this correctly, but it's still very possible.
Also, I would say that if you depend on said database resources/expensive 
initialization for your application to function properly, than I think it's 
ok to have a long initialization. Section 2.2 in chapter 2 of Erlang in 
Anger <http://www.erlang-in-anger.com/> has a very interesting discussion 
about this.

Maybe this is more suited to an external library (similar to (gen 
:P)connection)?

On Sunday, May 15, 2016 at 2:45:27 PM UTC+2, Michał Muskała wrote:
>
> Hello everybody, 
>
> Today GenServer (and all stdlib behaviours) are initialized 
> synchronously - only after init/1 returns the start_link function will 
> return. But in many places the initialization may be expensive or is 
> not essential to the GenServer's operation and can be, at least 
> partially, delayed. 
>
> There are couple solutions to this problem. One is sending itself a 
> message from init/1, which is error prone, because we have no 
> guarantees that this will be the first message received by the 
> process. The other one is to use :proc_lib or :gen directly, similar 
> to how it's used in the connection library 
> https://github.com/fishcakez/connection/blob/master/lib/connection.ex#L595 
> - this solution is correct, but very complicated and requires advanced 
> knowledge of OTP internals. 
>
> I'd like to propose adding another callback to GenServer called 
> delayed_init/1. that would be called if a new tuple {:delayed_init, 
> arg, state} is returned from init/1. The callback would be called 
> after  start_link returned, but before any message is processed by the 
> server. 
> The delayed_init/1 would support returning: 
> {:ok, state} - for entering normal GenServer loop 
> {:ok, state, timeout | :hibernate} - similar to init/1 
> {:stop, reason, state} - similar to the return value of call/3 and cast/2 
>
> This would allow to deal with the problem easily from application code 
> and simplify libraries such as connection significantly, removing all 
> the OTP plumbing code. 
>
> Example use cases include - opening sockets or ports, loading some 
> state from external resources like databases or doing some expensive 
> initialization that we know usually succeeds and that should not block 
> starting the supervision tree, awaiting the start of other parts of 
> the supervision tree or other applications before processing messages. 
>
> What do you think about that? 
>
> Michał. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/f766ac8f-a9e3-4bf7-a98a-ce280e7fd69e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to