Module elfo_core::coop

source ·
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.