Context
#114 tracks the broader 1.0 roadmap. This issue is narrower: it proposes a 0.8 breaking release as an intermediate cleanup step before the public API becomes harder to change.
The main goal is to clarify the boundaries between live spans, propagation context, async instrumentation, and collector backends.
Related issues: #172, #158, #92, #167, #171, #164.
0.7 deprecation release
Before 0.8, we can publish a 0.7.x release that deprecates APIs planned for removal:
fastrace::prelude
- old async instrumentation APIs such as
enter_on_poll
- async wrappers that require users to construct a live
Span and move it into the wrapper
0.8 can then remove them and update docs and examples to the new style.
Async instrumentation
The current async API exposes a low-level model:
future.in_span(Span::enter_with_parent("task", &root));
stream.in_span(Span::enter_with_parent("stream", &root));
For 0.8, we should avoid keeping this model under another name such as with_span(span). Instead, async APIs should be named by the lifetime of the span they create:
future.in_span("task", &root)
future.in_poll_span("poll")
stream.in_span("stream", &root)
stream.in_poll_span("poll")
stream.in_item_span("item")
in_span covers the whole future or stream. in_poll_span creates a short LocalSpan for each poll. in_item_span creates a span for each yielded stream item.
This also gives us a clearer migration path from tracing-futures and closes the main gap in #172.
Trace Context model
0.8 should move from case-by-case W3C helpers toward a coherent Trace Context model.
Suggested split:
Span // live span, owns timing and drop reporting
SpanContext // cheap internal parent and link context
TraceContext // W3C propagation boundary: traceparent and tracestate
TraceContext should be the W3C Trace Context type, including traceparent, tracestate, and trace flags.
This likely means changing the ID and flag model:
pub struct TraceId([u8; 16]);
pub struct SpanId([u8; 8]);
pub struct TraceFlags(u8);
That gives us a natural place to support both W3C flags: sampled and random-trace-id. It also addresses the wire-representation concern in #167.
ID validity
0.8 should remove APIs that make invalid IDs easy to create.
In particular, we should remove Default for TraceId, SpanId, and likely SpanContext, make ID fields private, and use checked construction or parsing for public APIs. All-zero trace IDs and span IDs should not be easy to construct accidentally.
This is the breaking cleanup already discussed in #92, #111, and #112.
TraceState
tracestate should be part of the propagation boundary, not an incidental Option<String> added to one helper.
A compact first version could be:
pub struct TraceState(Option<Arc<str>>);
That keeps pass-through cheap while leaving room for validation and vendor-entry updates later.
Collector and compatibility boundary
The current global collector design is still valuable: foreground work stays low, while aggregation and reporting happen in the background.
The issue is that frontend actions are tightly coupled to fastrace's own global command pipeline. This makes compatibility work harder, especially for the reverse direction of fastrace-tracing: producing fastrace spans into tracing so applications can reuse tracing reporters.
For 0.8, we should revisit whether span and local span actions can target a small core recording boundary before collector-specific aggregation happens. The existing global collector can remain the default backend, but the frontend action model should not make future tracing compatibility impossible.
Context
#114 tracks the broader 1.0 roadmap. This issue is narrower: it proposes a 0.8 breaking release as an intermediate cleanup step before the public API becomes harder to change.
The main goal is to clarify the boundaries between live spans, propagation context, async instrumentation, and collector backends.
Related issues: #172, #158, #92, #167, #171, #164.
0.7 deprecation release
Before 0.8, we can publish a 0.7.x release that deprecates APIs planned for removal:
fastrace::preludeenter_on_pollSpanand move it into the wrapper0.8 can then remove them and update docs and examples to the new style.
Async instrumentation
The current async API exposes a low-level model:
For 0.8, we should avoid keeping this model under another name such as
with_span(span). Instead, async APIs should be named by the lifetime of the span they create:in_spancovers the whole future or stream.in_poll_spancreates a shortLocalSpanfor each poll.in_item_spancreates a span for each yielded stream item.This also gives us a clearer migration path from
tracing-futuresand closes the main gap in #172.Trace Context model
0.8 should move from case-by-case W3C helpers toward a coherent Trace Context model.
Suggested split:
TraceContextshould be the W3C Trace Context type, includingtraceparent,tracestate, and trace flags.This likely means changing the ID and flag model:
That gives us a natural place to support both W3C flags:
sampledandrandom-trace-id. It also addresses the wire-representation concern in #167.ID validity
0.8 should remove APIs that make invalid IDs easy to create.
In particular, we should remove
DefaultforTraceId,SpanId, and likelySpanContext, make ID fields private, and use checked construction or parsing for public APIs. All-zero trace IDs and span IDs should not be easy to construct accidentally.This is the breaking cleanup already discussed in #92, #111, and #112.
TraceState
tracestateshould be part of the propagation boundary, not an incidentalOption<String>added to one helper.A compact first version could be:
That keeps pass-through cheap while leaving room for validation and vendor-entry updates later.
Collector and compatibility boundary
The current global collector design is still valuable: foreground work stays low, while aggregation and reporting happen in the background.
The issue is that frontend actions are tightly coupled to fastrace's own global command pipeline. This makes compatibility work harder, especially for the reverse direction of
fastrace-tracing: producing fastrace spans intotracingso applications can reuse tracing reporters.For 0.8, we should revisit whether span and local span actions can target a small core recording boundary before collector-specific aggregation happens. The existing global collector can remain the default backend, but the frontend action model should not make future
tracingcompatibility impossible.