Skip to content

Commit b8c8262

Browse files
committed
add TimeSkippingInfoUtil and unexpected data loss error
1 parent 4e89dc9 commit b8c8262

2 files changed

Lines changed: 85 additions & 8 deletions

File tree

service/history/timer_queue_active_task_executor.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package history
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"time"
87

@@ -26,6 +25,7 @@ import (
2625
"go.temporal.io/server/common/primitives/timestamp"
2726
"go.temporal.io/server/common/priorities"
2827
"go.temporal.io/server/common/resource"
28+
"go.temporal.io/server/common/softassert"
2929
"go.temporal.io/server/service/history/configs"
3030
"go.temporal.io/server/service/history/consts"
3131
"go.temporal.io/server/service/history/deletemanager"
@@ -947,10 +947,8 @@ func (t *timerQueueActiveTaskExecutor) executeTimeSkippingTimerTask(
947947
release(nil)
948948
return errNoTimerFired
949949
}
950-
// 2) fast-forward is disabled/reached, or this task was superseded by a newer fast-forward.
951-
// The versioned transition's TransitionCount identifies the specific fast-forward instance
952-
// (a re-applied fast-forward records a fresh transition), so a mismatch means this task is
953-
// stale and is dropped silently.
950+
951+
// 2) match current pending fast-forward
954952
if !tsiUtil.HasPendingFastForward() {
955953
release(nil)
956954
return errNoTimerFired
@@ -965,11 +963,17 @@ func (t *timerQueueActiveTaskExecutor) executeTimeSkippingTimerTask(
965963
taskVersion := task.VersionedTransition.GetNamespaceFailoverVersion()
966964
ffVersion := ffVT.GetNamespaceFailoverVersion()
967965
if err := CheckTaskVersion(t.shardContext, t.logger, mutableState.GetNamespaceEntry(), ffVersion, taskVersion, task); err != nil {
968-
release(nil)
969-
return errNoTimerFired
966+
// ErrTaskVersionMismatch: the framework drops the task and records the TaskVersionMisMatch metric.
967+
return err
970968
}
971969
} else {
972-
return errors.New("time skipping timer task validation failed: nil versioned transition")
970+
// Invariant: for a pending fast-forward and a task both exist, they must both have a non-nil versioned transition.
971+
errorMsg := fmt.Sprintf(
972+
"time-skipping timer task validation failed: VersionedTransition is nil (task: %t, pending fast-forward: %t)",
973+
task.VersionedTransition == nil,
974+
ffVT == nil,
975+
)
976+
return softassert.UnexpectedDataLoss(t.logger, errorMsg, nil)
973977
}
974978

975979
// 3) firing fast-forward timer (only turns off time skipping, and no task regeneration)

service/history/workflow/timeskipping_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,3 +1306,76 @@ func (s *mutableStateSuite) TestWrapTimeSourceWithTimeSkipping() {
13061306
s.Equal(fixedBase.Add(skipped), event.GetEventTime().AsTime())
13071307
})
13081308
}
1309+
1310+
func (s *mutableStateSuite) TestTimeSkippingInfoUtil() {
1311+
s.Run("NilTSISafe", func() {
1312+
util := NewTimeSkippingInfoUtil(nil)
1313+
s.False(util.HasPendingFastForward())
1314+
s.False(util.IsEnabled())
1315+
})
1316+
1317+
s.Run("NilFFISafe", func() {
1318+
s.mutableState.executionInfo.TimeSkippingInfo = &persistencespb.TimeSkippingInfo{
1319+
Config: &commonpb.TimeSkippingConfig{Enabled: true},
1320+
FastForwardInfo: nil,
1321+
}
1322+
util := NewTimeSkippingInfoUtil(s.mutableState.executionInfo.TimeSkippingInfo)
1323+
s.False(util.HasPendingFastForward())
1324+
})
1325+
1326+
s.Run("NoPendingFastForwardWhenHasReached", func() {
1327+
s.mutableState.executionInfo.TimeSkippingInfo = &persistencespb.TimeSkippingInfo{
1328+
Config: &commonpb.TimeSkippingConfig{Enabled: true},
1329+
FastForwardInfo: &persistencespb.FastForwardInfo{
1330+
HasReached: true,
1331+
TargetTime: timestamppb.New(time.Now()),
1332+
LastUpdateVersionedTransition: &persistencespb.VersionedTransition{
1333+
TransitionCount: 1,
1334+
NamespaceFailoverVersion: 1,
1335+
},
1336+
},
1337+
}
1338+
util := NewTimeSkippingInfoUtil(s.mutableState.executionInfo.TimeSkippingInfo)
1339+
s.False(util.HasPendingFastForward())
1340+
})
1341+
1342+
s.Run("NoPendingFastForwardWhenDisabled", func() {
1343+
s.mutableState.executionInfo.TimeSkippingInfo = &persistencespb.TimeSkippingInfo{
1344+
Config: &commonpb.TimeSkippingConfig{Enabled: false},
1345+
FastForwardInfo: &persistencespb.FastForwardInfo{
1346+
HasReached: false,
1347+
TargetTime: timestamppb.New(time.Now()),
1348+
LastUpdateVersionedTransition: &persistencespb.VersionedTransition{
1349+
TransitionCount: 1,
1350+
NamespaceFailoverVersion: 1,
1351+
},
1352+
},
1353+
}
1354+
util := NewTimeSkippingInfoUtil(s.mutableState.executionInfo.TimeSkippingInfo)
1355+
s.False(util.HasPendingFastForward())
1356+
})
1357+
1358+
s.Run("HasPendingFastForward", func() {
1359+
s.mutableState.executionInfo.TimeSkippingInfo = &persistencespb.TimeSkippingInfo{
1360+
Config: &commonpb.TimeSkippingConfig{Enabled: true},
1361+
FastForwardInfo: &persistencespb.FastForwardInfo{
1362+
HasReached: false,
1363+
TargetTime: timestamppb.New(time.Now()),
1364+
LastUpdateVersionedTransition: &persistencespb.VersionedTransition{
1365+
TransitionCount: 1,
1366+
NamespaceFailoverVersion: 1,
1367+
},
1368+
},
1369+
}
1370+
util := NewTimeSkippingInfoUtil(s.mutableState.executionInfo.TimeSkippingInfo)
1371+
s.True(util.HasPendingFastForward())
1372+
})
1373+
1374+
s.Run("IsEnabled", func() {
1375+
s.mutableState.executionInfo.TimeSkippingInfo = &persistencespb.TimeSkippingInfo{
1376+
Config: &commonpb.TimeSkippingConfig{Enabled: true},
1377+
}
1378+
util := NewTimeSkippingInfoUtil(s.mutableState.executionInfo.TimeSkippingInfo)
1379+
s.True(util.IsEnabled())
1380+
})
1381+
}

0 commit comments

Comments
 (0)