openlang

The Erlang and Elixir docs disagree about late call replies

The two sets of docs disagree about a call that timed out. The gen_server reference says that since OTP 24 calls go through a process alias, so a reply that arrives after the timeout is never received. The GenServer.call/3 page in the Elixir docs still tells you to discard late two-element tuples after catching the exit. Both sit on the same VM and the same gen module. I read the Elixir paragraph as left over. Either way the server still did the work, and neither page puts that up front.

The conversation continues 3

Follow the reasoning
  1. Permalink

    I love a docs mismatch. It's the easiest kind of fix to argue for. I'd keep half of that Elixir paragraph, though. The advice about discarding garbage tuples is stale for GenServer.call on a current OTP. The useful part is the sentence before it, that the caller exits while the server may still be working. Aliases don't change that at all.

    So a two-part rule for the docs. Drop the garbage-message advice for the call itself. Keep the bit about the server finishing anyway, and probably expand it, because a doctest showing {:ok, 1} will never tell anyone.

  2. Permalink

    The catching is the part I'd look at harder. Code that catches the timeout exit usually does it to retry. The first request is still in the server's queue or already running, so the retry runs the same operation a second time. The alias hides the first reply, and the first effect has happened anyway.

    If the operation only reads, fine. If it writes, the retry needs a request identity the server can check, or the caller should let the exit happen instead of retrying.

  3. Permalink

    On a current OTP the Erlang text is the one to trust. A server sleeps longer than the call allows and then replies. The caller wraps GenServer.call in catch :exit, _ and then runs flush(). Nothing. The late reply never shows up.

    patchkit's order is the one that costs something. Send a second call right after catching the first, and the server handles the first request to the end, then the second, so both side effects happen.

Other sides of the same question

  1. A println inside the swap! function

    The docs for swap! say the function may be called multiple times and should be free of side effects. Code in the wild still l…

    Replies 1clojure
  2. Isolate.run took my whole Loader with it

    Moved a big JSON decode off the main isolate with Isolate.run and got an error about an unsendable object instead of a speedu…

    Replies 2dart
  3. Workers stuck on the results send after the context is canceled

    Ran into a simple thing and spent longer on it than I'd like. A pool of eight workers reads tasks from jobs and writes result…

    Replies 8go