Class TyphonProfiler
Static lifecycle façade for the Tracy-style profiler. Manages the consumer drain thread, the per-exporter consume threads, and the exporter list.
public static class TyphonProfiler
- Inheritance
-
TyphonProfiler
- Inherited Members
Remarks
Start/Stop semantics: idempotent. Calling Typhon.Engine.TyphonProfiler.Start(Typhon.Engine.IResource,Typhon.Engine.ProfilerSessionMetadata,Typhon.Engine.ProfilerOptions,System.Action) on an already-running profiler is a no-op (does NOT throw). Calling Stop() on a stopped profiler is also a no-op. This avoids brittle test setup and accommodates restart-after-crash patterns.
Producer gate vs lifecycle: Typhon.Engine.TyphonProfiler.Start(Typhon.Engine.IResource,Typhon.Engine.ProfilerSessionMetadata,Typhon.Engine.ProfilerOptions,System.Action) does NOT enable the producer hot path. The producer gate is
ProfilerActive, which is set once at TelemetryConfig class load from the config file. If
ProfilerActive == false, calling Typhon.Engine.TyphonProfiler.Start(Typhon.Engine.IResource,Typhon.Engine.ProfilerSessionMetadata,Typhon.Engine.ProfilerOptions,System.Action) is harmless but no events will ever be emitted. If ProfilerActive == true,
events accumulate in slot ring buffers regardless of whether the profiler is started — until Typhon.Engine.TyphonProfiler.Start(Typhon.Engine.IResource,Typhon.Engine.ProfilerSessionMetadata,Typhon.Engine.ProfilerOptions,System.Action) is called there's just no consumer
to drain them, so eventually the producers see drops.
Exporter mutation: AttachExporter(IProfilerExporter)/DetachExporter(IProfilerExporter) are only valid while the profiler is stopped. Attempting to mutate the exporter list while running throws InvalidOperationException — concurrent mutation would race the consumer thread reading the list during fan-out.
Threading model: Start/Stop are serialized on a static lock. The consumer thread runs on its own (managed by
Typhon.Engine.Internals.ProfilerConsumerThread's Typhon.Engine.Internals.HighResolutionTimerServiceBase base). One dedicated OS thread per attached exporter runs
foreach (batch in exporter.Queue.GetConsumingEnumerable) { ProcessBatch; Release; } until CompleteAdding signals shutdown.
Properties
ActiveSlotCount
Number of slots currently claimed.
public static int ActiveSlotCount { get; }
Property Value
FinalDrainPasses
Diagnostic: how many final-drain passes ran before the consumer's AllSlotsEmpty returned true.
public static long FinalDrainPasses { get; }
Property Value
FinalDrainPendingBytes
Diagnostic: bytes still pending across all producer rings when the final drain stopped (snapshot at Stop()). Non-zero means tail records were lost.
public static long FinalDrainPendingBytes { get; }
Property Value
FinalDrainZeroProgressPasses
Diagnostic: how many final-drain passes drained zero bytes before the loop gave up (snapshot at Stop()).
public static long FinalDrainZeroProgressPasses { get; }
Property Value
FirstExporterBatchesProcessed
Diagnostic: batches/records the FIRST attached exporter actually processed (snapshot at Stop).
public static long FirstExporterBatchesProcessed { get; }
Property Value
FirstExporterRecordsProcessed
Diagnostic: records the first attached exporter actually processed (snapshot at Stop()).
public static long FirstExporterRecordsProcessed { get; }
Property Value
IsRunning
True while the profiler consumer thread is running.
public static bool IsRunning { get; }
Property Value
MainThreadId
Managed thread id of whichever thread called Typhon.Engine.TyphonProfiler.Start(Typhon.Engine.IResource,Typhon.Engine.ProfilerSessionMetadata,Typhon.Engine.ProfilerOptions,System.Action). The host's bootstrap flow is the
canonical "main" thread for the viewer. Zero while the profiler is stopped. Read by
ThreadSlotRegistry.AssignClaim to tag the corresponding slot's ThreadKind.
public static int MainThreadId { get; }
Property Value
SlotStateDump
Diagnostic: multi-line per-slot state dump captured at Stop(), or "(not captured)" when no snapshot was taken.
public static string SlotStateDump { get; }
Property Value
SpilloverPoolAcquiredCount
Snapshot of total spillover-buffer acquires across the session, captured at Stop() time. Each acquire corresponds to one chain-extension on a slot's overflow.
public static long SpilloverPoolAcquiredCount { get; }
Property Value
SpilloverPoolExhaustedCount
Snapshot of total spillover-pool exhaustions captured at Stop() time — overflow events that found the pool empty and fell back to the drop path. Non-zero means the configured SpilloverBufferCount was undersized for the workload.
public static long SpilloverPoolExhaustedCount { get; }
Property Value
TotalBatchesFannedOut
Diagnostic: batches/records the consumer fanned out (snapshot at Stop).
public static long TotalBatchesFannedOut { get; }
Property Value
TotalDroppedEvents
Total events dropped across all slots due to ring-buffer overflow.
public static long TotalDroppedEvents { get; }
Property Value
TotalDroppedExporterBatches
Snapshot of total exporter-queue drops captured at Stop() time (before the exporter list is cleared). Non-zero means the consumer produced batches faster than the exporter could drain them — events made it past the producer ring but didn't reach the sink (file / TCP wire). Distinct from TotalDroppedEvents which is producer-side ring overflow. Read AFTER Stop() for post-mortem diagnostics.
public static long TotalDroppedExporterBatches { get; }
Property Value
TotalRecordsFannedOut
Diagnostic: total records the consumer fanned out to exporters (snapshot at Stop()).
public static long TotalRecordsFannedOut { get; }
Property Value
Methods
AttachExporter(IProfilerExporter)
Attach an exporter. Must be called before Typhon.Engine.TyphonProfiler.Start(Typhon.Engine.IResource,Typhon.Engine.ProfilerSessionMetadata,Typhon.Engine.ProfilerOptions,System.Action) — attaching while running throws.
public static void AttachExporter(IProfilerExporter exporter)
Parameters
exporterIProfilerExporter
DetachExporter(IProfilerExporter)
Detach an exporter. Must be called while the profiler is stopped. Returns true if the exporter was found and removed.
public static bool DetachExporter(IProfilerExporter exporter)
Parameters
exporterIProfilerExporter
Returns
Stop()
Stop the profiler. Performs a final drain pass, signals all exporter queues to complete, joins all threads, then calls Flush() + Dispose() on each attached exporter. Idempotent.
public static void Stop()