437
}
438
440
return nil, err
441
}
442
443
// Query and append transient/speculative tasks if on last page
444
>
if len(continuationToken.PersistenceToken) == 0 {
api.go
445
>
// Re-query mutable state to detect events committed to DB during pagination (race condition fix).
446
>
// When a speculative/transient WFT times out or fails between the first and last DB page fetches,
447
>
// those events are committed to DB with IDs < continuationToken.NextEventId but were excluded
448
>
// because the DB fetch was capped at the original boundary. Fetch the gap now, then update
449
>
// the nextEventID boundary so appendTransientTasks validates against the correct ID.
450
>
_, _, _, freshNextEventID, freshIsRunning, freshVersionHistoryItem, freshVersionedTransition, freshTransientTasks, freshErr :=
451
>
queryMutableState(namespaceID, execution, common.EmptyEventID,
452
>
continuationToken.BranchToken, continuationToken.VersionHistoryItem, continuationToken.VersionedTransition)
453
>
if freshErr != nil {
454
return nil, freshErr
455
}
456
>
if freshNextEventID > continuationToken.NextEventId {
api.go
457
// Events were committed to DB during pagination — fetch the gap.
458
if freshErr = fetchGapEvents(continuationToken.NextEventId, freshNextEventID, continuationToken.BranchToken); freshErr != nil {