@@ -8,6 +8,7 @@ use uuid::Uuid;
88use crate :: Durable ;
99use crate :: error:: { ControlFlow , TaskError , TaskResult } ;
1010use crate :: task:: Task ;
11+ use crate :: types:: DurableEventPayload ;
1112use crate :: types:: {
1213 AwaitEventResult , CheckpointRow , ChildCompletePayload , ChildStatus , ClaimedTask , SpawnOptions ,
1314 TaskHandle ,
@@ -351,7 +352,9 @@ where
351352
352353 // Check cache for already-received event
353354 if let Some ( cached) = self . checkpoint_cache . get ( & checkpoint_name) {
354- return Ok ( serde_json:: from_value ( cached. clone ( ) ) ?) ;
355+ let durable_event_payload: DurableEventPayload =
356+ serde_json:: from_value ( cached. clone ( ) ) ?;
357+ return self . process_event_payload_wrapper ( durable_event_payload) ;
355358 }
356359
357360 // Check if we were woken by this event but it timed out (null payload)
@@ -383,10 +386,39 @@ where
383386 }
384387
385388 // Event arrived - cache and return
386- let payload = result. payload . unwrap_or ( JsonValue :: Null ) ;
387- self . checkpoint_cache
388- . insert ( checkpoint_name, payload. clone ( ) ) ;
389- Ok ( serde_json:: from_value ( payload) ?)
389+ let durable_event_payload = result. payload . unwrap_or ( DurableEventPayload {
390+ inner : JsonValue :: Null ,
391+ metadata : JsonValue :: Null ,
392+ } ) ;
393+ self . checkpoint_cache . insert (
394+ checkpoint_name,
395+ serde_json:: to_value ( durable_event_payload. clone ( ) ) ?,
396+ ) ;
397+
398+ self . process_event_payload_wrapper ( durable_event_payload)
399+ }
400+
401+ fn process_event_payload_wrapper < T : DeserializeOwned > (
402+ & self ,
403+ value : DurableEventPayload ,
404+ ) -> TaskResult < T > {
405+ #[ cfg( feature = "telemetry" ) ]
406+ {
407+ use opentelemetry:: KeyValue ;
408+ use opentelemetry:: trace:: TraceContextExt ;
409+ use tracing_opentelemetry:: OpenTelemetrySpanExt ;
410+
411+ let metadata: Option < HashMap < String , JsonValue > > =
412+ serde_json:: from_value ( value. metadata ) ?;
413+ if let Some ( metadata) = metadata {
414+ let context = crate :: telemetry:: extract_trace_context ( & metadata) ;
415+ tracing:: Span :: current ( ) . add_link_with_attributes (
416+ context. span ( ) . span_context ( ) . clone ( ) ,
417+ vec ! [ KeyValue :: new( "sentry.link.type" , "previous_trace" ) ] ,
418+ ) ;
419+ }
420+ }
421+ Ok ( serde_json:: from_value ( value. inner ) ?)
390422 }
391423
392424 /// Emit an event to this task's queue.
@@ -404,22 +436,13 @@ where
404436 )
405437 ) ]
406438 pub async fn emit_event < T : Serialize > ( & self , event_name : & str , payload : & T ) -> TaskResult < ( ) > {
407- if event_name. is_empty ( ) {
408- return Err ( TaskError :: Validation {
409- message : "event_name must be non-empty" . to_string ( ) ,
410- } ) ;
411- }
412-
413- let payload_json = serde_json:: to_value ( payload) ?;
414- let query = "SELECT durable.emit_event($1, $2, $3)" ;
415- sqlx:: query ( query)
416- . bind ( self . durable . queue_name ( ) )
417- . bind ( event_name)
418- . bind ( & payload_json)
419- . execute ( self . durable . pool ( ) )
420- . await ?;
421-
422- Ok ( ( ) )
439+ self . durable
440+ . emit_event ( event_name, payload, None )
441+ . await
442+ . map_err ( |e| TaskError :: EmitEventFailed {
443+ event_name : event_name. to_string ( ) ,
444+ error : e,
445+ } )
423446 }
424447
425448 /// Extend the task's lease to prevent timeout.
@@ -693,8 +716,11 @@ where
693716
694717 // Check cache for already-received event
695718 if let Some ( cached) = self . checkpoint_cache . get ( & checkpoint_name) {
696- let payload: ChildCompletePayload = serde_json:: from_value ( cached. clone ( ) ) ?;
697- return Self :: process_child_payload ( & step_name, payload) ;
719+ let durable_event_payload: DurableEventPayload =
720+ serde_json:: from_value ( cached. clone ( ) ) ?;
721+ let child_complete_payload: ChildCompletePayload =
722+ self . process_event_payload_wrapper ( durable_event_payload) ?;
723+ return Self :: process_child_payload ( & step_name, child_complete_payload) ;
698724 }
699725
700726 // Check if we were woken by this event but it timed out (null payload)
@@ -724,12 +750,18 @@ where
724750 }
725751
726752 // Event arrived - parse and return
727- let payload_json = result. payload . unwrap_or ( JsonValue :: Null ) ;
728- self . checkpoint_cache
729- . insert ( checkpoint_name, payload_json. clone ( ) ) ;
753+ let durable_event_payload = result. payload . unwrap_or ( DurableEventPayload {
754+ inner : JsonValue :: Null ,
755+ metadata : JsonValue :: Null ,
756+ } ) ;
757+ self . checkpoint_cache . insert (
758+ checkpoint_name,
759+ serde_json:: to_value ( durable_event_payload. clone ( ) ) ?,
760+ ) ;
730761
731- let payload: ChildCompletePayload = serde_json:: from_value ( payload_json) ?;
732- Self :: process_child_payload ( & step_name, payload)
762+ let child_complete_payload: ChildCompletePayload =
763+ self . process_event_payload_wrapper ( durable_event_payload) ?;
764+ Self :: process_child_payload ( & step_name, child_complete_payload)
733765 }
734766
735767 /// Process the child completion payload and return the appropriate result.
0 commit comments