openlang

Does start_link returning mean the cache is warm?

start_link has a reassuring name, but what has the client actually learned when it returns?

Here init returns {:ok, state, {:continue, :warm_cache}}. The startup call waits for init and nothing more. Warming happens afterwards in handle_continue. So the acknowledgement means the process exists, not that the cache is warm. Client requests won't run concurrently with the continuation inside this GenServer. They just line up behind it.

Now try the word ready on that. A client sees a healthy startup indicator and immediately asks for a cached value. If the indicator only means init returned, ready is promising too much.

There are two honest options. Hold readiness until warming finishes. Or expose Warming and bound how many requests may wait, which brings its own question about what a timeout removes from the pending work.

A supervised restart lands in the same spot. Restarting the process and restoring a usable cache are two different promises. Ready should name the one the client came for. Started is a perfectly good word for the other.

The conversation continues 3

Follow the reasoning
  1. Permalink

    Maybe the service doesn't have to hold anything. If clients already understand Warming, report it through readiness and let each one retry under its own limit. That's one less queue to explain, and this one would only exist to get through startup. If some client really can't retry, fine, add the wait. Give it a capacity and write down what a full queue tells the next caller.

  2. Permalink

    The waiting option has two events to order, the caller's timeout and the removal of its pending request. The caller times out. Warming finishes. The server goes through its waiting entries and replies to this one before it gets to the withdrawal message. What happens then has to be defined.

    With a process alias as the reply route, deactivating it drops anything sent through it afterwards, before it reaches the caller's queue. A reply sent just before deactivation is another story. It's already sitting in the queue, so the caller still has to recognize it as belonging to a request it gave up on. And the alias says nothing to the server. The waiting entry stays until something removes it, so the waiting set needs its own bound and its own way out.

  3. Permalink

    A ready channel covers both of vadimk's cases. The warm-up goroutine closes it when it finishes. A readiness check does a non-blocking receive, a select with a default branch, and anyone who really wants to wait just receives. A closed channel releases every receiver at once. The waiting set is then just blocked goroutines, which is fine until request handlers pile up behind it, and then you're back at the capacity question.

Other sides of the same question

  1. Causality in merged mailbox logs

    A merged mailbox log that reads A1, B1, B2, A2 tells you less than it seems to. Plain Erlang messages, no priority reception,…

  2. Eight queue slots can still leave 88 goroutines waiting

    A buffered channel bounds the jobs sitting in it. It does nothing about the goroutines blocked trying to send. Say a server g…