@@ -2,7 +2,7 @@ use opentelemetry::{
22 trace:: {
33 Link , SamplingDecision , SamplingResult , SpanKind , TraceContextExt , TraceId , TraceState ,
44 } ,
5- Context , KeyValue ,
5+ Context , KeyValue , TraceFlags ,
66} ;
77
88#[ cfg( feature = "jaeger_remote_sampler" ) ]
@@ -13,6 +13,8 @@ pub use jaeger_remote::{JaegerRemoteSampler, JaegerRemoteSamplerBuilder};
1313#[ cfg( feature = "jaeger_remote_sampler" ) ]
1414use opentelemetry_http:: HttpClient ;
1515
16+ const TRACE_FLAG_DEFERRED : TraceFlags = TraceFlags :: new ( 0x02 ) ;
17+
1618/// The [`ShouldSample`] interface allows implementations to provide samplers
1719/// which will return a sampling [`SamplingResult`] based on information that
1820/// is typically available just before the [`Span`] was created.
@@ -180,6 +182,12 @@ impl ShouldSample for Sampler {
180182 // The parent decision if sampled; otherwise the decision of delegate_sampler
181183 Sampler :: ParentBased ( delegate_sampler) => parent_context
182184 . filter ( |cx| cx. has_active_span ( ) )
185+ . map ( |cx| cx. span ( ) )
186+ . filter ( |span| {
187+ let trace_flags = span. span_context ( ) . trace_flags ( ) ;
188+ let is_deferred = trace_flags & TRACE_FLAG_DEFERRED == TRACE_FLAG_DEFERRED ;
189+ !is_deferred || trace_flags. is_sampled ( )
190+ } )
183191 . map_or_else (
184192 || {
185193 delegate_sampler
@@ -193,10 +201,8 @@ impl ShouldSample for Sampler {
193201 )
194202 . decision
195203 } ,
196- |ctx| {
197- let span = ctx. span ( ) ;
198- let parent_span_context = span. span_context ( ) ;
199- if parent_span_context. is_sampled ( ) {
204+ |span| {
205+ if span. span_context ( ) . is_sampled ( ) {
200206 SamplingDecision :: RecordAndSample
201207 } else {
202208 SamplingDecision :: Drop
@@ -249,7 +255,7 @@ pub(crate) fn sample_based_on_probability(prob: &f64, trace_id: TraceId) -> Samp
249255mod tests {
250256 use super :: * ;
251257 use crate :: testing:: trace:: TestSpan ;
252- use opentelemetry:: trace:: { SpanContext , SpanId , TraceFlags } ;
258+ use opentelemetry:: trace:: { SpanContext , SpanId } ;
253259 use rand:: random;
254260
255261 #[ rustfmt:: skip]
@@ -419,6 +425,30 @@ mod tests {
419425 ) ) ) ,
420426 SamplingDecision :: RecordAndSample ,
421427 ) ,
428+ (
429+ "should ignore deferred spans" ,
430+ Sampler :: AlwaysOn ,
431+ Context :: current_with_span( TestSpan ( SpanContext :: new(
432+ TraceId :: from( 1 ) ,
433+ SpanId :: from( 1 ) ,
434+ TRACE_FLAG_DEFERRED , // deferred
435+ false ,
436+ TraceState :: default ( ) ,
437+ ) ) ) ,
438+ SamplingDecision :: RecordAndSample ,
439+ ) ,
440+ (
441+ "should prioritize sampled flag over deferred" ,
442+ Sampler :: AlwaysOff ,
443+ Context :: current_with_span( TestSpan ( SpanContext :: new(
444+ TraceId :: from( 1 ) ,
445+ SpanId :: from( 1 ) ,
446+ TraceFlags :: SAMPLED | TRACE_FLAG_DEFERRED , // sampled and deferred (invalid state)
447+ false ,
448+ TraceState :: default ( ) ,
449+ ) ) ) ,
450+ SamplingDecision :: RecordAndSample ,
451+ ) ,
422452 ] ;
423453
424454 for ( name, delegate, parent_cx, expected) in test_cases {
0 commit comments