Skip to content

TaskProcessor uses an unbounded queue with no backpressure (latent soak leak) #124

Description

@ryanmurf

Summary

TaskProcessor (crates/asterisk-core/src/taskprocessor/mod.rs:36) backs its
serial executor with a mpsc::unbounded_channel, and push()
(:72) always enqueues and returns true — there is no high-water mark,
congestion signal, or backpressure. A producer that outpaces the single serial
consumer grows the queue (and process memory) without bound.

let (sender, mut receiver) = mpsc::unbounded_channel::<BoxedTask>();
...
pub fn push<F>(&self, task: F) -> bool {
    if let Some(sender) = &self.sender {
        self.task_count.fetch_add(1, Ordering::Relaxed);
        sender.send(Box::pin(task)).is_ok()   // never fails on capacity
    } else { false }
}

Real Asterisk's ast_taskprocessor has congestion control (a high-water alert
and overload shedding, tps_alert / AST_TASKPROCESSOR_HIGH_WATER_LEVEL); this
port has none.

Impact

Latent today: TaskProcessor is only referenced by the test framework and the
asterisk-core re-export — no production per-call path submits to it yet. But
the moment it is wired into a hot path (channel-op serialization, a media or
signaling fan-in), a slow task + fast producer is an unbounded memory growth
under the M5 soak, with no shedding and no observability beyond pending().

Recommendation

Before wiring TaskProcessor into any per-call path:

  • Use a bounded channel (or track depth against a configurable high-water mark)
    and make push shed / signal congestion instead of silently growing.
  • Surface an overload flag (mirror tps_alert) so callers can back off.

Filed as a hardening recommendation (not fixed here): adding backpressure to a
general primitive is a design choice for the owner, and the primitive is not yet
on a live path. Axis: concurrency / resource lifetime — unbounded queue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions