Spsc class final

SPSC (Single-Producer Single-Consumer) channels - Efficient direct communication.

A high-performance channel type in cross_channel. Optimized for scenarios where exactly one producer communicates with exactly one consumer. Uses efficient algorithms and data structures to minimize overhead.

Performance Characteristics

  • Good performance: Efficient message passing, typically ~550-570ns per operation (see benchmarks)
  • Minimal allocations: Optimized to reduce garbage collection pressure
  • Efficient design: Designed to avoid contention in the hot path
  • Ring buffer: Uses power-of-two sized SRSW (Single-Reader Single-Writer) ring buffer

When to Use SPSC

  • Performance-sensitive producer-consumer scenarios
  • Data streaming between two components
  • Game logic (e.g., main thread ↔ render thread communication)
  • Sensor data processing
  • Any scenario requiring efficient 1:1 communication

Constraints

EXACTLY one producer and one consumer required

  • Violation leads to undefined behavior and potential data corruption
  • Use XChannel.mpsc for multiple producers
  • Use XChannel.mpmc for multiple producers and consumers

Usage Patterns

High-frequency data streaming:

// Audio processing pipeline
final (tx, rx) = Spsc.channel<AudioSample>(capacity: 4096);

// Producer (audio thread)
void audioCallback(AudioSample sample) {
  final result = tx.trySend(sample);
  if (result is SendErrorFull) {
    // Buffer overrun - critical!
    handleBufferOverrun();
  }
}

// Consumer (processing thread)
await for (final sample in rx.stream()) {
  processAudioSample(sample);
}

Game engine messaging:

// Main thread → Render thread
final (renderCommands, renderRx) = Spsc.channel<RenderCommand>(capacity: 1024);

// Main thread
void updateGame() {
  final cmd = RenderCommand.drawSprite(sprite, position);
  await renderCommands.send(cmd);
}

// Render thread
while (engine.running) {
  switch (await renderRx.recv()) {
    case RecvOk(value: final cmd):
      executeRenderCommand(cmd);
    case RecvErrorDisconnected():
      break; // Shutdown
  }
}

IoT sensor pipeline:

// Sensor → Processing
final (sensorTx, sensorRx) = Spsc.channel<SensorReading>(capacity: 2048);

// High-frequency sensor (producer)
Timer.periodic(Duration(microseconds: 100), (timer) {
  final reading = SensorReading.now();
  sensorTx.trySend(reading); // Non-blocking
});

// Batch processor (consumer)
final batch = <SensorReading>[];
await for (final reading in sensorRx.stream()) {
  batch.add(reading);
  if (batch.length >= 100) {
    await processBatch(batch);
    batch.clear();
  }
}

Constructors

Spsc.new()

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited

Static Methods

channel<T>(int capacity, {String? metricsId}) → (SpscSender<T>, SpscReceiver<T>)
Creates an SPSC channel with the specified buffer capacity.