elixir-ecto/connection

handle_continue equivalent

JasonTrue opened this issue · 1 comments

In GenServer since OTP21 or so, there's a handle_continue callback for allowing asynchronous startup without accepting external messages until a required step or two are completed. Connection is meant to be a superset of GenServer functionality, and I suspect was originally motivated by the lack of handle_continue-like functionality in older GenServer versions, but does not (yet?) implement a handle_continue callback.

I have a scenario in which the Connection isn't truly "ready" to use until two TCP handshaking events are completed after establishing the initial gen_tcp connection.

the flow is basically like this:

  1. :gen_tcp.connect/4
  2. send a tcp message to a device to "register" a session
  3. The device sends a response, which I then parse and modify state using handle_info({:tcp, socket, message}, state)
  4. I then send another tcp request to request device metadata
  5. The device sends a response, which I then parse and store in state as well. At this point, my connection is ready to handle additional messages from any client.

I don't want to block start_link/init by waiting until this handshake is completely finished, because I start multiple connections of different types in the process supervision tree, so the normal async startup that Connection offers is desirable. But I also want to make sure these two handshaking events happen before I start allowing Elixir code to send messages to the connection.

Is there an "idiomatic" solution for this kind of multi-step connection situation in Connection? Obviously it's not quite :backoff but it's not exactly :ok in steps 1-4 above, but synchronous mode isn't quite a natural fit either.

I was originally planning on faking it with Process.send_after/3 and some curt replies to clients that try to do things before the handshaking is done. I see that Ecto's DBConnection uses Connection with a cast to self() to handle a sort-of similar set of issues.

Does it conceptually make sense to add handle_continue to Connection? I may be able to get around to putting together a PR for that if there's a sense that it's desirable, though I'm a bit worried about the added complexity with the various interactions between states that Connection supports.

We are no longer adding features to this project, please see the README notice. :)