@@ -683,29 +683,25 @@ func nonDeterminismDetail(opts IngestDurableTaskEventOpts, expectedKind sqlcv1.V
683683}
684684
685685type GetOrCreateLogEntryOpt struct {
686- Kind sqlcv1.V1DurableEventLogKind
687- IdempotencyKey []byte
688- LegacyIdempotencyKey []byte
689- InputPayload []byte
690- ResultPayload [] byte
691- NodeId int64
692- BranchId int64
693- IsSatisfied bool
694- UserMessage * string
695- WaitData string // JSON-encoded WaitData, empty string means no wait data
696- ChildTaskExternalId uuid.UUID
697- ShouldSkip bool
686+ Kind sqlcv1.V1DurableEventLogKind
687+ IdempotencyKey []byte
688+ InputPayload []byte
689+ ResultPayload []byte
690+ NodeId int64
691+ BranchId int64
692+ IsSatisfied bool
693+ UserMessage * string
694+ WaitData string // JSON-encoded WaitData, empty string means no wait data
695+ IsDagStepTrigger bool
696+ ChildTaskExternalId uuid.UUID
697+ ShouldSkip bool
698698 // IsTriggered creates the entry with triggered_at already set: the child's task rows exist
699699 // (an in-place replay), so there is no run left for the trigger path to spawn.
700700 IsTriggered bool
701701}
702702
703- func (o GetOrCreateLogEntryOpt ) idempotencyKeyMatches (existingKey []byte ) bool {
704- if bytes .Equal (o .IdempotencyKey , existingKey ) {
705- return true
706- }
707-
708- return len (o .LegacyIdempotencyKey ) > 0 && bytes .Equal (o .LegacyIdempotencyKey , existingKey )
703+ func (o GetOrCreateLogEntryOpt ) matchesExistingEntry (existing * sqlcv1.BulkGetDurableEventLogEntriesRow ) bool {
704+ return o .IsDagStepTrigger || bytes .Equal (o .IdempotencyKey , existing .IdempotencyKey )
709705}
710706
711707type GetOrCreateLogEntryOpts struct {
@@ -822,26 +818,14 @@ func satisfiedOrderPtr(v pgtype.Int8) *int64 {
822818}
823819
824820func (r * durableEventsRepository ) createIdempotencyKey (kind sqlcv1.V1DurableEventLogKind , triggerOpts * WorkflowNameTriggerOpts , waitForConditions []CreateExternalSignalConditionOpt ) ([]byte , error ) {
825- return hashIdempotencyKey (kind , triggerOpts , waitForConditions , true )
826- }
827-
828- func (r * durableEventsRepository ) createLegacyDagStepIdempotencyKey (triggerOpts * WorkflowNameTriggerOpts ) ([]byte , error ) {
829- if ! triggerOpts .IsDagStepTrigger {
830- return nil , nil
831- }
832-
833- return hashIdempotencyKey (sqlcv1 .V1DurableEventLogKindRUN , triggerOpts , nil , false )
834- }
835-
836- func hashIdempotencyKey (kind sqlcv1.V1DurableEventLogKind , triggerOpts * WorkflowNameTriggerOpts , waitForConditions []CreateExternalSignalConditionOpt , includeDagStepIdentity bool ) ([]byte , error ) {
837821 // note: can't use additional metadata here because it's not stable, since we store trace information in it w/ the otel instrumentors
838822 dataToHash := []byte (kind )
839823
840824 if triggerOpts != nil {
841825 dataToHash = append (dataToHash , triggerOpts .Data ... )
842826 dataToHash = append (dataToHash , []byte (triggerOpts .WorkflowName )... )
843827
844- if includeDagStepIdentity && triggerOpts .IsDagStepTrigger {
828+ if triggerOpts .IsDagStepTrigger {
845829 if triggerOpts .TargetActionId != nil {
846830 dataToHash = append (dataToHash , []byte (* triggerOpts .TargetActionId )... )
847831 }
@@ -1129,7 +1113,7 @@ func (r *durableEventsRepository) getOrCreateEventLogEntriesForTasks(
11291113 state .newEntryByKey [key ] = o
11301114 continue
11311115 }
1132- if ! o .idempotencyKeyMatches ( e . IdempotencyKey ) {
1116+ if ! o .matchesExistingEntry ( e ) {
11331117 nonDeterminismErr = & NonDeterminismError {
11341118 BranchId : o .BranchId ,
11351119 NodeId : o .NodeId ,
@@ -1288,7 +1272,7 @@ func (r *durableEventsRepository) getOrCreateEventLogEntriesForTasks(
12881272 return nil , nil , nil , fmt .Errorf ("expected to find log entry for skipped child task external id %s" , o .ChildTaskExternalId )
12891273 }
12901274
1291- if len (o .IdempotencyKey ) > 0 && ! o .idempotencyKeyMatches ( e . IdempotencyKey ) {
1275+ if len (o .IdempotencyKey ) > 0 && ! o .matchesExistingEntry ( e ) {
12921276 return nil , nil , nil , & NonDeterminismError {
12931277 BranchId : e .BranchID ,
12941278 NodeId : e .NodeID ,
@@ -2112,31 +2096,25 @@ func (r *durableEventsRepository) planDurableEventLogAppend(
21122096 // only index-based dedupe is validated against the existing entry's
21132097 // idempotency key: an explicit child_key intentionally reuses the
21142098 // cached child even when the inputs differ
2115- var idempotencyKey , legacyIdempotencyKey []byte
2099+ var idempotencyKey []byte
21162100 if triggerOpts .ChildKey == nil {
21172101 key , keyErr := r .createIdempotencyKey (sqlcv1 .V1DurableEventLogKindRUN , triggerOpts , nil )
21182102 if keyErr != nil {
21192103 return nil , fmt .Errorf ("failed to create idempotency key: %w" , keyErr ), nil
21202104 }
21212105 idempotencyKey = key
2122-
2123- legacyKey , legacyKeyErr := r .createLegacyDagStepIdempotencyKey (triggerOpts )
2124- if legacyKeyErr != nil {
2125- return nil , fmt .Errorf ("failed to create legacy idempotency key: %w" , legacyKeyErr ), nil
2126- }
2127- legacyIdempotencyKey = legacyKey
21282106 }
21292107
21302108 if _ , exists := childExternalIdToTriggerOpts [triggerOpts .ExternalId ]; ! exists {
21312109 childExternalIdToTriggerOpts [triggerOpts .ExternalId ] = triggerOpts
21322110 }
21332111
21342112 innerOpts [i ] = GetOrCreateLogEntryOpt {
2135- Kind : sqlcv1 .V1DurableEventLogKindRUN ,
2136- ChildTaskExternalId : triggerOpts .ExternalId ,
2137- IdempotencyKey : idempotencyKey ,
2138- LegacyIdempotencyKey : legacyIdempotencyKey ,
2139- ShouldSkip : true ,
2113+ Kind : sqlcv1 .V1DurableEventLogKindRUN ,
2114+ ChildTaskExternalId : triggerOpts .ExternalId ,
2115+ IdempotencyKey : idempotencyKey ,
2116+ IsDagStepTrigger : triggerOpts . IsDagStepTrigger ,
2117+ ShouldSkip : true ,
21402118 }
21412119 continue
21422120 }
@@ -2159,29 +2137,24 @@ func (r *durableEventsRepository) planDurableEventLogAppend(
21592137 return nil , fmt .Errorf ("failed to create idempotency key: %w" , keyErr ), nil
21602138 }
21612139
2162- legacyIdempotencyKey , legacyKeyErr := r .createLegacyDagStepIdempotencyKey (triggerOpts )
2163- if legacyKeyErr != nil {
2164- return nil , fmt .Errorf ("failed to create legacy idempotency key: %w" , legacyKeyErr ), nil
2165- }
2166-
21672140 // A child that is being cancelled or skipped never runs, so no completion event
21682141 // will arrive for it (trigger.go creates it directly in a terminal state,
21692142 // bypassing the match pipeline): its entry is terminal at creation regardless of
21702143 // whether this is a first run or a replay.
21712144 isSatisfied := triggerOpts .IsCancelled || triggerOpts .IsSkipped
21722145
21732146 innerOpts [i ] = GetOrCreateLogEntryOpt {
2174- Kind : sqlcv1 .V1DurableEventLogKindRUN ,
2175- NodeId : nodeId ,
2176- BranchId : branchId ,
2177- ChildTaskExternalId : triggerOpts .ExternalId ,
2178- IdempotencyKey : idempotencyKey ,
2179- LegacyIdempotencyKey : legacyIdempotencyKey ,
2180- InputPayload : inputPayload ,
2181- WaitData : marshalWaitData ( waitDataFromTriggerOpt ( triggerOpts )) ,
2182- UserMessage : triggerOpts .UserMessage ,
2183- IsSatisfied : isSatisfied ,
2184- IsTriggered : childrenToReplay [triggerOpts .ExternalId ],
2147+ Kind : sqlcv1 .V1DurableEventLogKindRUN ,
2148+ NodeId : nodeId ,
2149+ BranchId : branchId ,
2150+ ChildTaskExternalId : triggerOpts .ExternalId ,
2151+ IdempotencyKey : idempotencyKey ,
2152+ InputPayload : inputPayload ,
2153+ WaitData : marshalWaitData ( waitDataFromTriggerOpt ( triggerOpts )) ,
2154+ UserMessage : triggerOpts . UserMessage ,
2155+ IsDagStepTrigger : triggerOpts .IsDagStepTrigger ,
2156+ IsSatisfied : isSatisfied ,
2157+ IsTriggered : childrenToReplay [triggerOpts .ExternalId ],
21852158 }
21862159 }
21872160
0 commit comments