Another idea is to consider supporting explicit acknowledgement to the parent. If I’m not mistaken, the parent is blocked until :proc_lib.init_ack is invoked <https://github.com/erlang/otp/blob/maint/lib/stdlib/src/gen_server.erl#L330>. Perhaps the callback could call init_ack manually from init/1, to allow the parent to move on. However, now we need to inform the behaviour that we’ve already notified the parent ourselves, so it doesn’t send the ack again. Maybe introducing responses like {:acknowledged, standard_init_response} would do the trick.
Another (possibly ugly) variation is to introduce a wrapper function and use proc dict to cache acknowledgment. The client code could look like: def init(arg) do # do essential init here GenServer.send_ack() # do long running init, and return standard init response end While admittedly hacky, this has following benefits: 1. No need for additional init responses, which are possibly error prone anyway 2. No additional callback required 3. No need to store arg in the state 4. This code will crash explicitly on older versions. However, older code will work precisely as before. On the flip side, it’s a bit implicit and polymorphic - parent is notified after init, unless explicitly done from init/1. Relying on proc dict is also somewhat controversial, though not unprecedented. IIRC, OTP uses it for some internal stuff (e.g. $ancestors) already. Thoughts? > On 16 May 2016, at 15:27, Michał Muskała <[email protected]> wrote: > > I misunderstood the enter_loop function, I'm not fine with that as the > API after all. > > 2016-05-15 19:54 GMT+02:00 Saša Jurić <[email protected]>: >> I'd call the callback >> post_init, and make it non-optional. The callback then becomes a part of the >> GenServer lifecycle, and there are no changes to return tuples from init/1. >> The __using__ macro of GenServer could provide the default impl, which would >> do nothing, thus ensuring that there are no breaking changes. > > I like the name post_init better. > > The problems I see with an implicitly invoked callback are: > - it silently fails on older versions leaving the process not > initialized, while returning an unknown tuple would cause an error > - the initialization params need to be passed through state, so if > they are not normally part of the state now I need some additional > field to store them. > > -- > You received this message because you are subscribed to a topic in the Google > Groups "elixir-lang-core" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/elixir-lang-core/fLdVQDZcFo0/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/CAGAFNpnuiXOLP%2BuhUWGzm5XaDFYo35Lpz4NZdbNurtV4druvVQ%40mail.gmail.com. > For more options, visit https://groups.google.com/d/optout. -- 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/3A2A82FE-3604-4131-BEE1-5A5C29F93875%40gmail.com. For more options, visit https://groups.google.com/d/optout.
