Profiler Launch Override Hook
Adjust the resolved profiler launch config in code, on top of file/env, without giving up zero-code defaults.
Status: โ Implemented ยท Visibility: Public ยท Level: ๐ฃ Advanced ยท Category: Hosting
๐ฏ What it solves
The profiler self-wires from typhon.telemetry.json (+ TYPHON__PROFILER__* env vars) with zero host
code. Some hosts still need to decide the trace path or live port in code โ e.g. layering --trace/
--live CLI args on top of the file config, or computing a per-run trace path (timestamped, per-match,
per-test-case) that a static JSON value can't express. This hook adds that one escape hatch without
requiring every host to hand-roll profiler bootstrap.
โ๏ธ How it works (in brief)
AddTyphonProfiler registers a delegate that maps the config resolved from file + environment to the
effective ProfilerLaunchConfig. The engine's runtime bootstrap (TyphonRuntime.Create) resolves and
applies it automatically when profiling starts โ no other wiring is needed. If the delegate returns
null, the resolved config is used unchanged. Precedence is fixed: JSON file โ environment โ
your delegate. If you never call AddTyphonProfiler, nothing changes โ the zero-code self-wiring path
runs exactly as before.
๐ป Usage
using Microsoft.Extensions.DependencyInjection;
using Typhon.Engine;
var services = new ServiceCollection();
services.AddDatabaseEngine();
// Layer CLI args on top of typhon.telemetry.json / env โ CLI wins where it sets a value.
services.AddTyphonProfiler(resolved => resolved.MergedWith(ProfilerLaunchConfig.FromArgs(args)));
var provider = services.BuildServiceProvider();
var engine = provider.GetRequiredService<DatabaseEngine>();
// serviceProvider must be passed here for the override to be resolved and applied.
var runtime = TyphonRuntime.Create(engine, sched => { /* register systems */ }, serviceProvider: provider);
| Registration | Effect |
|---|---|
AddTyphonProfiler(resolved => resolved.MergedWith(ProfilerLaunchConfig.FromArgs(args))) |
CLI flags (--trace, --live [port], --live-wait <ms>) override unset-only fields of the file/env config. |
AddTyphonProfiler(resolved => resolved with { TraceFilePath = ComputePath() }) |
Fully computed trace path, ignoring whatever the file/env supplied. |
โ ๏ธ Guarantees & limits
- Opt-in, additive. Calling
AddTyphonProfilernever changes behavior unless theIServiceProvideris also passed toTyphonRuntime.Createโ the override is only resolved from that container. - โ ๏ธ Zero-arg call resolves to a different, unrelated overload.
Typhon.Enginealso declaresTelemetryServiceExtensions.AddTyphonProfiler(IServiceCollection)(forces earlyTelemetryConfiginit; no delegate parameter). C# overload resolution prefers that exact-arity match over this hook's optional-parameter overload, soservices.AddTyphonProfiler()with no argument silently calls the other method and never registers aProfilerLaunchOverride. Always pass a delegate explicitly to reach this hook. - Cannot enable profiling from a closed master gate. The delegate only runs once
typhon.telemetry.json's masterTyphon:Profiler:Enabledis already on; it can add or change where output goes (trace file / live port), not flip profiling on for a session where it's off. If the resulting config still has no output channel, nothing is exported. - Best-effort. Profiler startup โ including your delegate โ runs inside a try/catch that never crashes the host; a throwing delegate disables profiling for that session with a logged diagnostic, it does not fault application startup.
- Runs once per process. The hook fires the first time
TyphonRuntime.Createself-wires the profiler; it is not re-invoked per runtime instance.
๐งช Tests
- ProfilerLaunchConfigTests โ
MergedWithprecedence (MergedWith_OverrideTraceWinsWhenSet,_BaseRetainedWhenOverrideUnset,_NullOverride_ReturnsBase) andTypicalLayering_ConfigFirstThenArgsOverride, which its own comment ties directly to "theAddTyphonProfilerhook"; no fixture callsAddTyphonProfileritself โ this covers the merge logic the delegate composes over
๐ Related
- Source:
TyphonBuilderExtensions.cs(AddTyphonProfiler),ProfilerBootstrap.cs(TryStart),ProfilerLaunchConfig.cs,TyphonRuntime.cs(Create) - Colliding overload:
TelemetryServiceExtensions.cs(AddTyphonProfiler(IServiceCollection), no delegate) - Sibling: Profiler Session Lifecycle & Zero-Code Bootstrap โ the zero-code self-wiring this hook layers an override on top of.