Repository navigation
Conversation
4 of 5 tasks
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 16:38
29736b8 to
c6e5aa6
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 16:40
c6e5aa6 to
f4697dc
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 16:53
f4697dc to
e653227
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 17:09
e653227 to
8db4d1e
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 17:14
8db4d1e to
cb8ca81
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 17:22
cb8ca81 to
6e0908c
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 17:34
6e0908c to
bd0e889
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 17:42
bd0e889 to
189e001
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 18:04
189e001 to
c02481a
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 18:20
c02481a to
a03ba52
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 19:19
7c4e075 to
a9f4db1
Compare
reka18
force-pushed
the
fix/durable-timers
branch
2 times, most recently
from
November 5, 2026 19:39
fe18571 to
ac8edcd
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 19:48
ac8edcd to
e509532
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 20:10
e509532 to
39d8e39
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 20:23
39d8e39 to
1738b1a
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 20:52
1738b1a to
372a253
Compare
reka18
force-pushed
the
fix/durable-timers
branch
from
November 5, 2026 21:02
372a253 to
b33de98
Compare
Contributor
Author
|
Review results. One reviewer per dimension, each reading the others' findings. All seven dimensions have zero blockers on the latest round. Fixed along the way: the Handle's timer table now follows the scheduler, and each chained timer takes the deadline the scheduler armed. Replay aligns on each Record, so older journals with a misplaced settle read recover, including across a restart. Every fix has a test confirmed to fail without it. Fuzzing journals this PR writes found no mismatch in about 80,000 operations per run. Known limits, in the changelog: two kinds of older journal can't be repaired and can fail |
This was referenced Nov 9, 2026
Start now arms the initial state's timers and carries them in the baseline. Recovery re-arms checkpointed timers before the tail replays, so one fired in the tail isn't missed. RunService records the clock read that arms a timer, and replay arms it. A tick that fires nothing records nothing, so a timer loop no longer grows the journal. Relates to #214. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this change does
Timers survive recovery, and idle ticks stop growing the journal. Stacked on #235.
Startarms the initial state's timers and carries them in the baseline. An instance started before this change keeps its initial timer unarmed.RunServicerecords the clock read that arms a timer, and replay arms it, in bothRecoverandStateAt.durable, sostateis untouched.Recover: an instance that continued after an older recovery missed a fired timer, and a checkpoint taken after a tick that followed a settle or whose clock moved mid-tick, which can hold a wrong timer table. No reader can tell these journals apart. An idleTickdoesn't touch the Store, so a stale owner finds out on its next real step, not on the idle tick.StateAtalso re-arms the baseline's timers, so a timer armed byStartor carried by a checkpoint fires in the replayed window.Known and left open: a timer whose transition fails is consumed and reported only in its
FireResult.Err, not inTick's error (#214 question 8), which theTickgodoc now says. Checkpoints still grow with trace history, and the size metric #214 question 9 proposes has no home yet.DeliverToActorpasses no effects to the scheduler, so a state entered by delivery never arms its timer.Tickdoesn't absorb service or actor effects, so a timer entering an invoke state doesn't start the service live, and a timer that leaves and re-enters one can makeRecoverfail. Both exist on the base.Why
Startnever armed the initial state's timers, even live, so an instance starting in a timed state now fires a timer it didn't before. A timer fired after a checkpoint, or armed by a service result, was missed on replay. Every idle tick appended a Record.Relates to: #214
Evidence
On
GOTOOLCHAIN=go1.27.3, indurable:go test ./...TestClock_StartInTimedState_ArmsTimer,TestClock_TickWithNothingDue_AppendsNoRecord,TestClock_TickWithNoTimer_AppendsNoRecord,TestService_TimerArmedBySettle_ReplaysOnRecoverandTestTimerCheckpoint_FiredAfterCheckpoint_ByteIdenticalgo test -race ./...golangci-lintChecklist
git commit -s) per the DCOtype: subject)mage checkpasses locally (lint + race tests + govulncheck): not run as a wholeTestStateAt_TimerArmedAtStart_Fires, the older-journalTestRecover_OlderJournal_*tests, and the timer tests above