Long gen_server init question (not about order of messages :)

Roger Lipscombe roger@REDACTED
Tue May 18 10:10:31 CEST 2021


- The server is a singleton (within the node).
- While the server is initializing, a caller should get 'not_ready'.
It should not block.

I can see two ways to do this, both involving an extra process:

1. The proxy starts up the server, passing self(). When the server is
ready, it notifies the proxy. If the proxy receives a request while
the server's not ready, it replies with 'not_ready'. If the server's
ready, the proxy passes the request on.
2. The server starts in 'not_ready' mode, and starts a worker. The
worker does the initialization, and when it's done, it sends the
resulting state to the server. From that point, the server can reply
to requests.

If you want to do this without an extra process:

- The server starts. It's initially unregistered. Any calls to the
server look up the registration. If it's not registered, the call
returns 'not_ready'. When it's ready, the server registers itself,
meaning that calls can find the pid and make the call.

We use a variant of this in production.

On Sat, 15 May 2021 at 19:55, Stanislav Ledenev <s.ledenev@REDACTED> wrote:
> Hi!
> Need advice from an experienced community about synchronizing long initializing gen_server with other parts of application.
> Let's say we have 4 gen_servers:
> * mod_api       - accept requests;
> * mod_func      - real job;
> * mod_x, mod_y  - users of mod_func.
> mod_api accepts requests and transforms them to calls to mod_x, mod_y.
> mod_func is crucial for the application but it needs a time consuming procedure
> of initialization. IRL it is some cryptography related stuff.
> While mod_func is in the initialization state, mod_api must return 'not_ready' for all requests.
> While mod_func initializing it is not available for any requests.
> I was thinking about options of notification mechanism implementation and see two of them:
> 1. Some kind of polling from mod_api to mod_func with gen_server:call with timeout: mod_api after initialization begin send_after loop with timeout call to mod_func;
> 2. gen_event based solution. Run up gen_event and wait for notification about readiness of mod_func.
> Am I missing something? Are there any better solutions for such a task?

More information about the erlang-questions mailing list