MLServe.ModelServer (MLServe v0.1.0)

Copy Markdown View Source

Owns one model version's lifecycle: loading, readiness, status and draining.

Loading never blocks the supervisor

init/1 returns immediately with status :loading and defers the actual work to handle_continue/2. A model that takes thirty seconds to memory-map from disk would otherwise hold up Supervisor.start_link/2 for thirty seconds, and with several such models an application could exceed its own start timeout and fail to boot at all.

Until loading finishes, MLServe.predict/3 returns {:error, :model_not_ready} and MLServe.ready?/1 returns false — which is exactly what a Kubernetes readiness probe should see. Use MLServe.await_ready/2 when you need to block.

Load failures retry with backoff

A failed load does not crash the process. Model artifacts live on network mounts, object-store fuse layers and volumes that attach a moment after the container starts; crashing would burn the supervisor's restart intensity in seconds and take down the whole instance permanently. Instead the load is retried with exponential backoff, and after the final attempt the model is marked :failed with the reason preserved in MLServe.model_status/2.

Draining

Unload is graceful. The model is marked :draining so the registry stops routing new requests to it, then this process waits for the in-flight counter to reach zero before terminating the workers. Requests already accepted finish; requests not yet accepted go elsewhere. Only after :drain_timeout elapses are stragglers abandoned, and the count that was still outstanding is reported as the drained measurement on [:ml_serve, :model, :unload].

Summary

Functions

Returns a specification to start this module under a supervisor.

Drains in-flight requests and returns the number still outstanding when the wait ended.

Returns the loaded backend state. Used by tests and by reload.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

drain(name, version, timeout)

@spec drain(atom(), String.t(), timeout()) ::
  {:ok, non_neg_integer()} | {:error, term()}

Drains in-flight requests and returns the number still outstanding when the wait ended.

state(name, version)

@spec state(atom(), String.t()) :: {:ok, term()} | {:error, :model_not_ready}

Returns the loaded backend state. Used by tests and by reload.