Table of Contents

Class ExporterQueue

Namespace
Typhon.Engine
Assembly
Typhon.Engine.dll

Bounded handoff queue between the profiler consumer thread and one exporter. Wraps a BlockingCollection<T> with explicit drop-newest semantics on full, and balances the batch refcount on drop so the pool doesn't leak.

public sealed class ExporterQueue : IDisposable
Inheritance
ExporterQueue
Implements
Inherited Members

Remarks

Why BlockingCollection<T>? It's the BCL primitive that gives us a bounded queue plus the GetConsumingEnumerable(CancellationToken) blocking-iterator pattern that the exporter's dedicated thread runs:

foreach (var batch in queue.GetConsumingEnumerable(ct)) { exporter.ProcessBatch(batch); batch.Release(); }
No async/await, no thread-pool churn, just a sync exporter thread per exporter draining a bounded channel.

Drop-newest on full: if Typhon.Engine.ExporterQueue.TryEnqueue(Typhon.Engine.TraceRecordBatch) finds the queue at capacity, it drops the new batch (does not block the consumer thread) and increments DroppedBatches. Critically, it ALSO calls Typhon.Engine.TraceRecordBatch.Release on the dropped batch — without this, the batch's refcount would never reach zero and the pool would leak. With it, the refcount stays balanced no matter how many exporter queues drop a given batch on a given drain pass.

Why drop the newest, not the oldest? The newest batch hasn't started processing yet — dropping it costs nothing besides the loss of those events, while dropping the oldest would either require a complex rewind or invalidate work the exporter is in the middle of doing. Tracy's design philosophy: "prefer losing a sample to blocking the producer."

Constructors

ExporterQueue(int)

Create a queue bounded to boundedCapacity batches; excess enqueues drop-newest once full.

public ExporterQueue(int boundedCapacity)

Parameters

boundedCapacity int

Maximum batches held before drop-newest engages. Must be ≥ 1.

Exceptions

ArgumentOutOfRangeException

boundedCapacity is less than 1.

Properties

DroppedBatches

Total batches dropped due to a full queue. Read by diagnostics.

public long DroppedBatches { get; }

Property Value

long

Methods

Dispose()

Dispose the underlying BlockingCollection<T>. Call after the exporter thread has exited its consume loop.

public void Dispose()

GetConsumingEnumerable(CancellationToken)

Returns the blocking iterator that the exporter thread foreaches over. Yields each enqueued batch and exits when Typhon.Engine.ExporterQueue.CompleteAdding has been called and the queue is drained.

public IEnumerable<TraceRecordBatch> GetConsumingEnumerable(CancellationToken cancellationToken)

Parameters

cancellationToken CancellationToken

Returns

IEnumerable<TraceRecordBatch>