@@ -1222,68 +1222,91 @@ def my_controller(url, headers):
12221222 :param dict headers: HTTP headers to extract tracing attributes.
12231223 :return: New `Context` with propagated attributes.
12241224 """
1225- context = Context ()
1225+ # Fast path: empty or no extraction config
12261226 if not headers or not config ._propagation_style_extract :
1227- return context
1227+ return Context ()
1228+
12281229 try :
12291230 style = ""
1231+ # Normalize header keys once
12301232 normalized_headers = {name .lower (): v for name , v in headers .items ()}
1231- # tracer configured to extract first only
1233+ prop_styles = config ._propagation_style_extract
1234+
1235+ # Short-circuit: first-only extraction mode
12321236 if config ._propagation_extract_first :
1233- # loop through the extract propagation styles specified in order, return whatever context we get first
1234- for prop_style in config ._propagation_style_extract :
1235- propagator = _PROP_STYLES [prop_style ]
1236- context = propagator ._extract (normalized_headers )
1237- style = prop_style
1237+ for ps in prop_styles :
1238+ # baggage handled later
1239+ if ps == _PROPAGATION_STYLE_BAGGAGE :
1240+ continue
1241+ context = _PROP_STYLES [ps ]._extract (normalized_headers )
1242+ style = ps
12381243 if context :
1239- _record_http_telemetry ("context_header_style.extracted" , prop_style )
1240- if config ._propagation_http_baggage_enabled is True :
1241- _attach_baggage_to_context (normalized_headers , context )
1242- break
1243-
1244- # loop through all extract propagation styles
1244+ _record_http_telemetry ("context_header_style.extracted" , ps )
1245+ if config ._propagation_http_baggage_enabled :
1246+ _attach_baggage_to_context (normalized_headers , context )
1247+ break
1248+ else :
1249+ context = Context ()
12451250 else :
1246- contexts , styles_w_ctx = HTTPPropagator ._extract_configured_contexts_avail (normalized_headers )
1247- # check that styles_w_ctx is not empty
1251+ # Multi-style extraction: collect all contexts in a single tight loop
1252+ contexts = []
1253+ styles_w_ctx = []
1254+ append = contexts .append
1255+ append_style = styles_w_ctx .append
1256+ for ps in prop_styles :
1257+ if ps == _PROPAGATION_STYLE_BAGGAGE :
1258+ continue
1259+ c = _PROP_STYLES [ps ]._extract (normalized_headers )
1260+ if c :
1261+ _record_http_telemetry ("context_header_style.extracted" , ps )
1262+ append (c )
1263+ append_style (ps )
12481264 if styles_w_ctx :
12491265 style = styles_w_ctx [0 ]
1250-
1266+ # Context resolution: fast-path single, else resolve
12511267 if contexts :
1252- context = HTTPPropagator ._resolve_contexts (contexts , styles_w_ctx , normalized_headers )
1253- if config ._propagation_http_baggage_enabled is True :
1268+ if len (contexts ) == 1 :
1269+ context = contexts [0 ]
1270+ else :
1271+ context = HTTPPropagator ._resolve_contexts (contexts , styles_w_ctx , normalized_headers )
1272+ if config ._propagation_http_baggage_enabled :
12541273 _attach_baggage_to_context (normalized_headers , context )
1274+ else :
1275+ context = Context ()
12551276
1256- # baggage headers are handled separately from the other propagation styles
1257- if _PROPAGATION_STYLE_BAGGAGE in config ._propagation_style_extract :
1277+ # Baggage extraction, always handled last, only once
1278+ baggage_context = None
1279+ if _PROPAGATION_STYLE_BAGGAGE in prop_styles :
12581280 baggage_context = _BaggageHeader ._extract (normalized_headers )
12591281 if baggage_context ._baggage != {}:
1260- # Record telemetry for successful baggage extraction
12611282 _record_http_telemetry ("context_header_style.extracted" , _PROPAGATION_STYLE_BAGGAGE )
12621283 if context :
12631284 context ._baggage = baggage_context .get_all_baggage_items ()
12641285 else :
12651286 context = baggage_context
12661287
1288+ # Tagging of baggage keys, single pass
12671289 if config ._baggage_tag_keys :
1268- raw_keys = [k .strip () for k in config ._baggage_tag_keys if k .strip ()]
1269- # wildcard: tag all baggage keys
1270- if "*" in raw_keys :
1290+ keys = [k .strip () for k in config ._baggage_tag_keys if k .strip ()]
1291+ if "*" in keys :
12711292 tag_keys = baggage_context .get_all_baggage_items ().keys ()
12721293 else :
1273- tag_keys = raw_keys
1274-
1275- for stripped_key in tag_keys :
1276- if (value := baggage_context .get_baggage_item (stripped_key )) is not None :
1277- prefixed_key = BAGGAGE_TAG_PREFIX + stripped_key
1278- if prefixed_key not in context ._meta :
1279- context ._meta [prefixed_key ] = value
1280-
1294+ tag_keys = keys
1295+ meta = context ._meta
1296+ bag_dict = baggage_context .get_all_baggage_items ()
1297+ for k in tag_keys :
1298+ v = bag_dict .get (k )
1299+ if v is not None :
1300+ prefixed = BAGGAGE_TAG_PREFIX + k
1301+ if prefixed not in meta :
1302+ meta [prefixed ] = v
1303+
1304+ # Propagation behavior: restart, done last for correctness
12811305 if config ._propagation_behavior_extract == _PROPAGATION_BEHAVIOR_RESTART :
12821306 link = HTTPPropagator ._context_to_span_link (context , style , "propagation_behavior_extract" )
12831307 context = Context (baggage = context .get_all_baggage_items (), span_links = [link ] if link else [])
12841308
12851309 return context
1286-
12871310 except Exception :
12881311 log .debug ("error while extracting context propagation headers" , exc_info = True )
1289- return Context ()
1312+ return Context ()
0 commit comments