Repository navigation
Commit 9cbb654
authored
End a timed-out run's wait at its deadline, whoever cancelled the row (#635)
Fixes #627.
## The problem
A workflow past its deadline is cancelled by whichever comes first: its
own timer or the database-side timeout sweep, which runs on every
executor. The timer cancelled the run's future, which is what ends a
local handle's `getResult()`, only when `cancelOwnedWorkflow(workflowId,
ownerXid)` succeeded, that is, only while the run still owned the row.
If the sweep (on any executor) settled the row first, the timer found
nothing to cancel and left the future alone. `getResult()` then waited
until the run's next write was refused: through a whole `dbos.sleep`, 30
s for a 1 s timeout in #627.
## The fix
- **The timer always ends the wait at the deadline.** It still cancels
the row only while the run owns it, but it cancels the run's future
either way. That happens in a `finally`, so a cancel that fails against
the database still ends the wait.
- **`getResult()` reports what the row records.** When the future was
cancelled, it awaits the row instead of assuming a cancellation. That
gives:
- cancelled, whether by this run, the sweep on any executor, or an
explicit cancel;
- if the workflow was resumed after the timeout, the resumed run's
outcome. The handle used to report that case as a cancellation.
- **A run whose body has finished is left alone.** Such a run only
records or adopts its outcome, so it completes its own future promptly.
Cancelling it would make `getResult()` return a copy deserialized from
the row instead of the value the run holds: for a portable workflow
returning a record, a `Map`.
- **The timer is dropped when the run finishes first.** It used to stay
queued until the deadline, holding the run's future and so its result.
The run's future now cancels its timer on completion, and the timeout
scheduler (`setRemoveOnCancelPolicy(true)`) removes cancelled tasks
instead of keeping them until their delay runs out.
As before, cancelling the future doesn't stop the run's thread, because
`CompletableFuture.cancel` doesn't interrupt. The run keeps going until
its next write is refused. What changes is that `getResult()` no longer
waits for it.
The first commit took a different approach: the sweep completed the
handles of local runs whose rows it cancelled. It only helped the
executor whose sweep won the row, so the second commit reverts it.
## Behaviour changes for a handle whose deadline passed
- If the row has since been deleted, `getResult()` throws
`DBOSNonExistentWorkflowException` instead of reporting a cancellation.
- If the workflow was resumed, `getResult()` waits for the resumed run.
## Tests
- `WorkflowTimeoutSweepTest`:
- `aRunTheSweepCancelsFirstStillEndsAtItsDeadline`: the sweep cancels
the row before the run's timer fires.
- `aRowAnotherExecutorCancelledEndsTheWaitAtTheDeadline`: the row is
cancelled the way another executor's sweep would.
- `aHandleReportsTheOutcomeOfARunResumedAfterTheTimeout`.
Each waits until the run is inside its sleep, where nothing else would
end the wait. All three fail against main's `DBOSExecutor`.
- `TimeoutTest.aFinishedRunLeavesNoTimerQueued`: fails without either
the timer cancel or the remove-on-cancel policy.
🤖 Generated with [Claude Code](https://claude.com/claude-code)1 parent 614fedd commit 9cbb654
5 files changed
Lines changed: 276 additions & 12 deletions
File tree
- transact/src
- main/java/dev/dbos/transact/execution
- test/java/dev/dbos/transact
- execution
- txstep
- workflow
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| 96 | + | |
96 | 97 | | |
97 | 98 | | |
98 | 99 | | |
| |||
325 | 326 | | |
326 | 327 | | |
327 | 328 | | |
328 | | - | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
329 | 334 | | |
330 | 335 | | |
331 | 336 | | |
| |||
1599 | 1604 | | |
1600 | 1605 | | |
1601 | 1606 | | |
1602 | | - | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
1603 | 1610 | | |
1604 | 1611 | | |
1605 | 1612 | | |
| |||
2597 | 2604 | | |
2598 | 2605 | | |
2599 | 2606 | | |
| 2607 | + | |
| 2608 | + | |
| 2609 | + | |
| 2610 | + | |
| 2611 | + | |
2600 | 2612 | | |
2601 | 2613 | | |
2602 | 2614 | | |
| |||
2650 | 2662 | | |
2651 | 2663 | | |
2652 | 2664 | | |
| 2665 | + | |
2653 | 2666 | | |
2654 | 2667 | | |
2655 | 2668 | | |
| |||
2694 | 2707 | | |
2695 | 2708 | | |
2696 | 2709 | | |
| 2710 | + | |
2697 | 2711 | | |
2698 | 2712 | | |
2699 | 2713 | | |
| |||
2731 | 2745 | | |
2732 | 2746 | | |
2733 | 2747 | | |
2734 | | - | |
2735 | | - | |
2736 | | - | |
2737 | | - | |
2738 | | - | |
2739 | | - | |
2740 | | - | |
2741 | | - | |
2742 | | - | |
2743 | | - | |
| 2748 | + | |
| 2749 | + | |
| 2750 | + | |
| 2751 | + | |
| 2752 | + | |
| 2753 | + | |
| 2754 | + | |
| 2755 | + | |
| 2756 | + | |
| 2757 | + | |
| 2758 | + | |
| 2759 | + | |
| 2760 | + | |
| 2761 | + | |
| 2762 | + | |
| 2763 | + | |
| 2764 | + | |
| 2765 | + | |
| 2766 | + | |
| 2767 | + | |
| 2768 | + | |
| 2769 | + | |
| 2770 | + | |
| 2771 | + | |
2744 | 2772 | | |
2745 | 2773 | | |
2746 | 2774 | | |
2747 | 2775 | | |
2748 | 2776 | | |
| 2777 | + | |
| 2778 | + | |
| 2779 | + | |
| 2780 | + | |
2749 | 2781 | | |
2750 | 2782 | | |
2751 | 2783 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
9 | 11 | | |
10 | 12 | | |
11 | 13 | | |
| |||
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
26 | 33 | | |
27 | 34 | | |
28 | 35 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| 24 | + | |
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
| |||
49 | 51 | | |
50 | 52 | | |
51 | 53 | | |
| 54 | + | |
| 55 | + | |
52 | 56 | | |
53 | 57 | | |
54 | 58 | | |
| |||
58 | 62 | | |
59 | 63 | | |
60 | 64 | | |
| 65 | + | |
61 | 66 | | |
62 | 67 | | |
63 | 68 | | |
| |||
118 | 123 | | |
119 | 124 | | |
120 | 125 | | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
121 | 134 | | |
122 | 135 | | |
123 | 136 | | |
| |||
257 | 270 | | |
258 | 271 | | |
259 | 272 | | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
260 | 311 | | |
261 | 312 | | |
262 | 313 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
237 | 237 | | |
238 | 238 | | |
239 | 239 | | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
240 | 265 | | |
241 | 266 | | |
242 | 267 | | |
| |||
0 commit comments