Expand description
Provides a cooperative budget for actors.
§The Problem
A single call to an actor’s poll
may potentially do a lot of work before
it returns Poll::Pending
. If an actor runs for a long period of time
without yielding back to the executor, it can starve other actors waiting on
that executor to execute them, or drive underlying resources. Since Rust
does not have a runtime, it is difficult to forcibly preempt a long-running
task. Instead, this module provides an opt-in mechanism for actors to
collaborate with the executor to avoid starvation.
This approach is similar to the one used in tokio.
§Supported budgets
Elfo supports two kinds of budgeting for actors:
- by time: the actor yields to the executor after a certain amount of time, 5ms by default.
- by count: the actor yields to the executor after a certain number of
consume_budget()
calls, 64 by default.
A used kind is determined by the presence of telemetry. It’s a controversial
decision, but the reason is that telemetry requires fast time source
(usually, TSC), which is provided by the quanta
crate. In this case, time
measurements are negligible and a time-based budget is preferred as a more
reliable way to prevent starvation.
Note that methods Context::recv()
and Context::try_recv()
call
consume_budget()
already, so you don’t need to think about budgeting
in most cases.
These limits cannot be configured for now.
§Coordination with tokio’s budget system
Tokio has its own budget system, which is unstable and cannot be used by elfo. Thus, elfo’s budget system is independent of tokio’s and work simultaneously.
However, since both budgets are reset at start of each actor’s poll, no matter which budget is exhausted first, both system work coordinately.
Functions§
- Consumes a unit of budget and returns the execution back to the executor, but only if the actor’s coop budget has been exhausted.