Evaluate many states against one question set, concurrently.
The question set is validated and encoded once; each state then gets its own
TypeSafeAPI.evaluate/4 call in a task. Results come back in input order by
default, one {:ok, result} or {:error, error} per state, so a single
failure never hides the other results.
Concurrency
max_concurrency defaults to 8. That number is a guess: TypeSafe has not
published rate limits or an SLA at the time of writing. Raise it if your
account allows, and watch for :rate_limited errors (the retry policy
absorbs short bursts of 429s before they surface).
Tasks run under TypeSafeAPI.TaskSupervisor, started by
TypeSafeAPI.Application, and are not linked to the caller. A task that
raises - a Req adapter blowing up, a state that will not JSON-encode -
becomes one {:error, %TypeSafeAPI.Error{type: :unexpected}} in that state's
position instead of killing the calling process and every other in-flight
request with it.
Two timeouts
:timeout means the same thing here as in TypeSafeAPI.evaluate/4: the
timeout of a single HTTP attempt, passed straight through to each call.
:task_timeout is the cap on one state's whole task, every retry and every
backoff delay included. It defaults to the call's retry budget plus one
attempt timeout, or 60 000 ms when the budget is disabled, which is the
longest a well-behaved call can take. A state that overruns it comes back as
{:error, %TypeSafeAPI.Error{type: :timeout}}.
When retries run out
A state whose retries are exhausted is not special. It comes back as an
ordinary {:error, %TypeSafeAPI.Error{type: :rate_limited, retry_after_ms: ms}}
in that state's position, next to the states that succeeded, and the batch
keeps going. With on_error: :raise that same error is raised instead, once
every task has been collected.
With ordered: false the outcomes arrive as they finish rather than in
input order, so under on_error: :raise the error that raises is the first
one to finish, which is not necessarily the earliest state in the input.
If you need the failure to be reproducible, keep ordered: true.
retry_after_ms is carried on the error so the caller can back off before
the next batch. The per-call retry policy has already given up by the time
you see it, so the useful move is to sleep for the longest retry_after_ms
in the batch, then resend just the failed states.
The one failure that is not per-state
An invalid question set fails before any request is sent, so there is no
per-state outcome to put it in. evaluate_many/4 then returns a bare
{:error, %TypeSafeAPI.Error{type: :validation}} rather than a list - the
reason the return type is a union. Match on it, or pass on_error: :raise,
which raises that error too rather than handing back a tuple from the mode
whose whole point is not to.
Passing a %TypeSafeAPI.SystemOne.Prepared{} from
TypeSafeAPI.SystemOne.prepare/1 instead of a question set skips both the
re-validation and that failure mode.
Summary
Functions
Evaluates each state in states against questions.
The options evaluate_many/4 handles itself.
Types
@type outcome() :: {:ok, TypeSafeAPI.Result.t()} | {:error, TypeSafeAPI.Error.t()}
Functions
@spec evaluate_many( TypeSafeAPI.Client.t(), Enumerable.t(), TypeSafeAPI.Question.input() | TypeSafeAPI.SystemOne.Prepared.t(), keyword() ) :: [outcome()] | {:error, TypeSafeAPI.Error.t()}
Evaluates each state in states against questions.
questions is a question set, or a %TypeSafeAPI.SystemOne.Prepared{} from
TypeSafeAPI.SystemOne.prepare/1.
Returns a list of outcomes (in input order unless ordered: false), or
{:error, error} when the question set itself is invalid.
Options
:max_concurrency(pos_integer/0) - Maximum number of in-flight requests. A guess; see the module docs. The default value is8.:task_timeout- Cap in milliseconds on one state's whole task, covering every retry and delay. Defaults to the retry budget plus one attempt timeout, or 60 000 when the budget is disabled. Not to be confused with:timeout, which is one HTTP attempt, as inTypeSafeAPI.evaluate/4.:ordered(boolean/0) - Return results in input order.falseyields them as they finish. The default value istrue.:on_error-:collectreturns error tuples in place;:raiseraises the first error. The default value is:collect.
Every other option (:model, :timeout, :retry, :req_options,
:telemetry) is passed to each call and means what it means in
TypeSafeAPI.evaluate/4; see TypeSafeAPI.SystemOne.options_schema/0.
@spec options_schema() :: NimbleOptions.t()
The options evaluate_many/4 handles itself.
Every other option is passed through to each individual call; see
TypeSafeAPI.SystemOne.options_schema/0.
:max_concurrency(pos_integer/0) - Maximum number of in-flight requests. A guess; see the module docs. The default value is8.:task_timeout- Cap in milliseconds on one state's whole task, covering every retry and delay. Defaults to the retry budget plus one attempt timeout, or 60 000 when the budget is disabled. Not to be confused with:timeout, which is one HTTP attempt, as inTypeSafeAPI.evaluate/4.:ordered(boolean/0) - Return results in input order.falseyields them as they finish. The default value istrue.:on_error-:collectreturns error tuples in place;:raiseraises the first error. The default value is:collect.