@@ -635,14 +635,30 @@ def span_events(self, settings, attr_class=dict):
635635 )
636636 )
637637 ct_exit_spans = {"instrumented" : 0 , "kept" : 0 , "dropped_ids" : 0 }
638- yield from self .root .span_events (
639- settings ,
640- base_attrs ,
641- parent_guid = self .parent_span ,
642- attr_class = attr_class ,
643- partial_granularity_sampled = self .partial_granularity_sampled ,
644- ct_exit_spans = ct_exit_spans ,
645- )
638+ # In corner case scenarios where there is a harvest while spans are being added
639+ # to the reservoir, a compact span may be sent before its agent attributes have
640+ # been updated. This is solved by cacheing all spans in compact mode and not
641+ # adding them to the reservoir until all spans are touched.
642+ if self .partial_granularity_sampled and settings .distributed_tracing .sampler .partial_granularity .type == "compact" :
643+ events = [event for event in self .root .span_events (
644+ settings ,
645+ base_attrs ,
646+ parent_guid = self .parent_span ,
647+ attr_class = attr_class ,
648+ partial_granularity_sampled = self .partial_granularity_sampled ,
649+ ct_exit_spans = ct_exit_spans ,
650+ )]
651+ for event in events :
652+ yield event
653+ else :
654+ yield from self .root .span_events (
655+ settings ,
656+ base_attrs ,
657+ parent_guid = self .parent_span ,
658+ attr_class = attr_class ,
659+ partial_granularity_sampled = self .partial_granularity_sampled ,
660+ ct_exit_spans = ct_exit_spans ,
661+ )
646662 # If this transaction is partial granularity sampled, record the number of spans
647663 # instrumented and the number of spans kept to monitor cost savings of partial
648664 # granularity tracing.
0 commit comments