Commit 73569aa
committed
Don't schedule a move-later alarm if an interleaving commit setAlarm()
Prior to yielding to the event loop when we try to persist to SQLite, we
save the current alarm time in `alarmStateForCommit`. When we come back
after the operation completes, this value remains unchanged, but
`alarmScheduledNoLaterThan` may have changed while we were async.
Prior to this commit, that meant we might schedule a move-later alarm
synchronization with the alarm manager if `alarmScheduledNoLaterThan`
was now earlier than `alarmStateForCommit`, even if
`alarmStateForCommit` was set to the currently durable (and synced!)
alarm time.
Consider the following:
1. SQLite and the alarm manager have an alarm time of 2 years from now.
2. The application does a large SQL insert, starting commit 1. We yield
to the event loop in `commitImpl` when we try to persist the write to
SQLite, but save `alarmStateForCommit` as the current alarm time
(2 years from now)
3. The application does a setAlarm() to run the alarm in 5 minutes. This
is a "move-earlier" operation, so we sync to the alarm manager
eagerly.
4. The alarm manager now has an alarm time 5 minutes in the future, and
we start trying to persist the setAlarm in 5 minutes to SQLite.
5. The first commit from (2) continues after persisting its large SQL
insert. It sees `alarmStateForCommit` is 2 years from now, and
`alarmScheduledNoLaterThan` is 5 minutes from now. We decide to do a
background "move-later" sync with the alarm manager, then finish the
commit.
6. The second commit from (3) finishes persisting the 5 minute alarm to
SQLite and finishes its commit.
7. The background "move-later" alarm from (5) modifies the alarm
manager's state to have an alarm time of 2 years in the future.
The end state is we essentially miss the "move-earlier" update in the
alarm manager, breaking our model of "move-early eagerly and
move-later lazily".
**The fix**
We track `alarmVersion`, which is incremented every time the application
calls setAlarm(). We capture this value before starting to persist to
SQLite and compare it against the current `alarmVersion` after continuing
commitImpl. If our captured `alarmVersion` differs from the current
version, then the application called setAlarm() while our SQLite commit
was in-flight, and so we can safely skip attempting a move-later sync
with the alarm manager, since a subsequent commit will modify the alarm
anyways.1 parent 19b0534 commit 73569aa
File tree
3 files changed
+47
-27
lines changed- src/workerd/io
3 files changed
+47
-27
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1045 | 1045 | | |
1046 | 1046 | | |
1047 | 1047 | | |
1048 | | - | |
| 1048 | + | |
| 1049 | + | |
| 1050 | + | |
1049 | 1051 | | |
1050 | 1052 | | |
1051 | 1053 | | |
| |||
1054 | 1056 | | |
1055 | 1057 | | |
1056 | 1058 | | |
1057 | | - | |
| 1059 | + | |
1058 | 1060 | | |
1059 | 1061 | | |
1060 | 1062 | | |
1061 | | - | |
1062 | 1063 | | |
1063 | 1064 | | |
1064 | 1065 | | |
| |||
1067 | 1068 | | |
1068 | 1069 | | |
1069 | 1070 | | |
1070 | | - | |
1071 | | - | |
1072 | | - | |
1073 | | - | |
1074 | 1071 | | |
1075 | 1072 | | |
1076 | 1073 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
433 | 433 | | |
434 | 434 | | |
435 | 435 | | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
436 | 442 | | |
437 | 443 | | |
438 | 444 | | |
| |||
449 | 455 | | |
450 | 456 | | |
451 | 457 | | |
452 | | - | |
453 | | - | |
454 | | - | |
455 | | - | |
456 | | - | |
457 | | - | |
458 | | - | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
459 | 487 | | |
460 | | - | |
461 | | - | |
462 | | - | |
463 | | - | |
464 | | - | |
465 | | - | |
466 | | - | |
467 | | - | |
468 | | - | |
469 | | - | |
470 | | - | |
471 | | - | |
472 | | - | |
473 | 488 | | |
474 | 489 | | |
475 | 490 | | |
| |||
642 | 657 | | |
643 | 658 | | |
644 | 659 | | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
645 | 663 | | |
646 | 664 | | |
647 | 665 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
239 | 239 | | |
240 | 240 | | |
241 | 241 | | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
242 | 247 | | |
243 | 248 | | |
244 | 249 | | |
| |||
0 commit comments