Commit cd00964
authored
🐛 fix resource destruction order (#1091)
There was a regression introduced with
#1081 such that when a task was
halted, its resources were being shut down _before_ the task body was
finished. This resulted in violation of the structured concurrency
guarantees that required everything in scope to remain alive until
after the body of the task is fully executed. This is because the body
of the operation may use resources that are in scope throughout the
_entirety_ of the operation. For example, in the following code, the
finally block of the main operation requires the `child` task to be
fully complete.
```ts
let task = run(function* () {
let synchronize = withResolvers<void>();
let child = yield* spawn(() => synchronize.operation);
try {
yield* suspend();
} finally {
synchronize.resolve();
yield* child;
}
});
await task.halt() // deadlock!
```
Because the main task dependes on `child`, child needs to be active
and only halted _after_ the main task is complete, _not_ before. (in
this case the antecedent resource is a simple spawned `Task`, but it
could be anything; a database connection, file handle, whatever...).
Only after all references to the resource have become inactive can the
resource be destroyed.
When destroying a scope then, we need to first destroy oneself by
interrupting effect iteration, and only once that is complete, destroy
child scopes. This is accomplished by not reversing scope destructors.
It turns out this regression was actually being surfaced by the an
existing testcase which we commented out 😬. Another test has been
added to ensure the proper shutdown order is preserved when explicitly
halting.
> Note: in the future we will simplify this process even further by
removing the scope "destructor" mechanism altogether and replacing it
with middleware. This will replace fiddling with the order of
registration and execution with explicit declaration of sequence of
operations as "around" or "within" other operations.1 parent 253ce61 commit cd00964
4 files changed
Lines changed: 63 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
77 | | - | |
| 77 | + | |
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
110 | 141 | | |
111 | 142 | | |
112 | 143 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
211 | 211 | | |
212 | 212 | | |
213 | 213 | | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
| 214 | + | |
218 | 215 | | |
219 | 216 | | |
220 | 217 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
228 | 258 | | |
0 commit comments