MLServe.Dispatcher (MLServe v0.1.0)

Copy Markdown View Source

The prediction hot path: route, admit, cache, hook, dispatch, record.

Everything in this module runs in the calling process — a Phoenix controller, an Oban job, a Task. Nothing here is a GenServer, and that is the point: MLServe adds no serialisation point between your request and the model.

The order of operations is deliberate:

route lookup (1 ETS read)
   admission control (atomic counter)
     telemetry span opens
       cache lookup
         preprocess hook
           dispatch
           postprocess hook
         cache write
     telemetry span closes
   counters settled

Cache, hooks and validation all happen before dispatch, so a worker is occupied only for the duration of actual inference. A preprocess hook that queries Postgres for stored features runs on the caller's own scheduler time, never on a GPU worker's.

Dispatch strategies

ModelPath
concurrency: :shared:persistent_term.get/1 then the backend, in this process. No message passing, no copies.
batching: configuredGenServer.call to the model's MLServe.Batcher, which coalesces concurrent callers.
concurrency: :exclusivePick a worker, GenServer.call it.

Summary

Functions

batch_predict(name, inputs, opts)

@spec batch_predict(atom(), [term()], keyword()) :: {:ok, [term()]} | {:error, term()}

Runs a batch prediction. See MLServe.batch_predict/3.

predict(name, input, opts)

@spec predict(atom(), term(), keyword()) :: {:ok, term()} | {:error, term()}

Runs a single prediction. See MLServe.predict/3.