Commit 5139759
committed
fix: shorten checkpoint wait for blocked caller
The checkpoint collector waited on an empty queue after it had already
collected a synchronous checkpoint. A synchronous checkpoint has a
caller blocked until the batch is persisted, and a blocked caller cannot
enqueue more work. So that wait could not enlarge the batch. It only
delayed the caller by the shutdown-signal poll interval of 100 ms.
Sequential steps paid that cost once per step. Measured in us-east-1 on
python3.13 at 1024 MB over 1000 steps, warm, comparing this change
against d61985e:
median interval between StepSucceeded 142 ms -> 41 ms
p95 interval 163 ms -> 62 ms
invocation duration 144.4 s -> 43.1 s
steps per second 6.92 -> 23.22
The step body performs no I/O, so nearly all of the removed time was the
idle wait.
Changes
- Track whether a batch holds a synchronous checkpoint. Set the flag on
all three insertion paths: the overflow drain, the first blocking
read, and the additional read.
- Once set, wait only _BLOCKED_CALLER_WAIT_SECONDS on an empty queue
instead of the full poll interval. Work already queued still joins the
batch, so an asynchronous step START still travels in the same request
as its synchronous SUCCEED. Sequential steps keep one checkpoint call
of two updates per step, unchanged.
- Wait 1 ms rather than not at all. Branch threads start one at a time,
so gaps in checkpoint arrivals occur while a parallel or map thread
pool starts. Not waiting cut extra small batches during that startup.
On Lambda, waiting 1 ms produced the same checkpoint call count as
d61985e at both 200 and 500 branches, and ran 1.21x to 1.28x faster.
- Include empty synchronous checkpoints. ConcurrentExecutor collects
every due branch, calls create_checkpoint() once for the whole resume
wave, then resubmits. So a wide map resume enqueues one empty
checkpoint, not one per branch, and the full window would delay that
single caller with nothing to coalesce.
- Leave asynchronous-only batching unchanged. With no blocked caller the
wait costs no latency and still reduces the API call count.
- Name the existing 0.1 second literal _STOP_SIGNAL_POLL_SECONDS. Both
waits in the collector are now named, so the min() compares two named
intervals rather than one named value and one literal.
- Correct the max_batch_time_seconds docstring. It bounds the total
collection window, not the idle wait, which the poll interval caps
regardless of the configured value.
Neither constant is reachable by an end user, so this changes no public
signature. CheckpointBatcherConfig is absent from the package exports,
no caller outside state.py passes batcher_config, and config.py has no
batcher settings.
Tests
Add six collector tests that assert the timeout values passed to the
queue read rather than elapsed time. The collector's waiting policy is
fully described by those timeouts, so the tests need no sleeps and no
wall-clock thresholds. Five of the six fail when the shortened wait is
removed. The sixth pins the asynchronous-only path this change leaves
alone.
Rewrite test_create_checkpoint_multiple_sync_calls_all_block. Its old
assertion required each caller to block for at least 0.15 s, but each
caller started its clock after the processor began its 0.15 s sleep, so
its own elapsed time was always under that. The assertion held only
because the collector added 100 ms on top, which is the defect. The test
now proves the invariant by observation order and uses no delay at all.
It waits until all three operations are queued, asserts no caller has
returned, collects the batch, asserts no caller has returned, then sets
the completion events and asserts every caller returned. Settling the
waiters before collection fails it.
Correct the description in map_with_concurrent_waits_int_test. It said
the test mirrors the resubmitter issuing one empty checkpoint per
branch. ConcurrentExecutor issues one per resume wave, so the test
exercises a synthetic burst. It still guards the batch-limit behaviour
that #325 changed.
Fixes #7101 parent 8742ad9 commit 5139759
3 files changed
Lines changed: 264 additions & 72 deletions
File tree
- packages/aws-durable-execution-sdk-python
- src/aws_durable_execution_sdk_python
- tests
- e2e
Lines changed: 38 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
50 | 58 | | |
51 | 59 | | |
52 | 60 | | |
53 | 61 | | |
54 | 62 | | |
55 | 63 | | |
56 | 64 | | |
57 | | - | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
58 | 69 | | |
59 | 70 | | |
60 | 71 | | |
| |||
1025 | 1036 | | |
1026 | 1037 | | |
1027 | 1038 | | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
| 1044 | + | |
| 1045 | + | |
| 1046 | + | |
1028 | 1047 | | |
1029 | 1048 | | |
1030 | 1049 | | |
| |||
1037 | 1056 | | |
1038 | 1057 | | |
1039 | 1058 | | |
| 1059 | + | |
| 1060 | + | |
| 1061 | + | |
1040 | 1062 | | |
1041 | 1063 | | |
1042 | 1064 | | |
1043 | 1065 | | |
1044 | 1066 | | |
1045 | 1067 | | |
1046 | 1068 | | |
| 1069 | + | |
| 1070 | + | |
1047 | 1071 | | |
1048 | 1072 | | |
1049 | 1073 | | |
| |||
1071 | 1095 | | |
1072 | 1096 | | |
1073 | 1097 | | |
1074 | | - | |
1075 | | - | |
| 1098 | + | |
| 1099 | + | |
1076 | 1100 | | |
1077 | 1101 | | |
| 1102 | + | |
| 1103 | + | |
1078 | 1104 | | |
1079 | 1105 | | |
1080 | 1106 | | |
| |||
1101 | 1127 | | |
1102 | 1128 | | |
1103 | 1129 | | |
1104 | | - | |
| 1130 | + | |
1105 | 1131 | | |
1106 | 1132 | | |
1107 | 1133 | | |
1108 | 1134 | | |
1109 | 1135 | | |
1110 | 1136 | | |
1111 | | - | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
1112 | 1143 | | |
| 1144 | + | |
| 1145 | + | |
1113 | 1146 | | |
1114 | 1147 | | |
1115 | 1148 | | |
| |||
Lines changed: 16 additions & 18 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
12 | | - | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
13 | 16 | | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
26 | | - | |
27 | | - | |
28 | | - | |
| 27 | + | |
29 | 28 | | |
30 | 29 | | |
31 | 30 | | |
| |||
92 | 91 | | |
93 | 92 | | |
94 | 93 | | |
95 | | - | |
| 94 | + | |
96 | 95 | | |
97 | | - | |
98 | | - | |
99 | | - | |
| 96 | + | |
| 97 | + | |
100 | 98 | | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
105 | 103 | | |
106 | 104 | | |
107 | 105 | | |
| |||
0 commit comments