Commit 7ca2b51
authored
fix: fail over unhealthy Daytona sandbox hosts (#183)
## Summary
- Detect Daytona's explicit host-recovery start rejection at the
provider boundary.
- Replace only the stopped canonical runtime while retaining the user's
mounted workspace-volume subpath.
- Extend durable preparation retries so remaining transient provider
failures do not become immediate failed runs.
## Architecture
A run still resolves the single canonical user sandbox first. If Daytona
reports that the sandbox's assigned host is recovering, the existing
runtime-replacement fence verifies the active-run lease and canonical
volume identity, removes the disposable container, and creates one
replacement attached to the same isolated volume subpath. Cloudflare
Workflow retries remain the durable fallback around preparation.
## Decisions Made
| Decision | Choice | Alternatives considered | Reasoning |
| --- | --- | --- | --- |
| Host-local recovery | Replace the disposable runtime | Wait
indefinitely; fail the run | The workspace is on a separate persistent
volume, so failover preserves user files and avoids dependence on one
unhealthy runner. |
| Failure classification | Match Daytona's explicit 503 host-recovery
rejection | Replace on every 503 | A narrow provider-boundary classifier
prevents destructive failover during platform-wide outages. |
| Remaining transient failures | Six exponential-backoff preparation
retries | Tight polling inside the Worker | Durable retries do not hold
an isolate or hammer Daytona. |
## Edge Cases Handled
| Scenario | Handling |
| --- | --- |
| Another run owns the sandbox | Existing lease fence refuses
replacement. |
| Sandbox identity or volume mount is ambiguous | Existing
canonical-runtime assertions fail closed. |
| Daytona changes or omits the host-recovery message | No forced
replacement; durable preparation retries apply. |
| Replacement creation is temporarily unavailable | The Workflow retries
the idempotent preparation step. |
## Verification
- [x] `pnpm lint`
- [x] `pnpm typecheck`
- [x] `pnpm turbo build --force`
- [x] `pnpm deadcode`
- [x] `pnpm architecture:check`
- [x] `pnpm turbo skills:build`
- [ ] Resume the failed production Pomodoro run after deployment and
verify the replacement sandbox preserves the project and serves the
generated preview.1 parent 37219e3 commit 7ca2b51
5 files changed
Lines changed: 62 additions & 10 deletions
File tree
- apps/agent-worker
- src/durable-objects
- packages/agent-core/src/tools/code
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
84 | 89 | | |
85 | 90 | | |
86 | 91 | | |
| |||
Lines changed: 4 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
50 | | - | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
51 | 54 | | |
52 | 55 | | |
53 | 56 | | |
| |||
Lines changed: 30 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
2 | 6 | | |
3 | 7 | | |
4 | 8 | | |
| |||
59 | 63 | | |
60 | 64 | | |
61 | 65 | | |
| 66 | + | |
| 67 | + | |
62 | 68 | | |
63 | 69 | | |
64 | 70 | | |
| |||
265 | 271 | | |
266 | 272 | | |
267 | 273 | | |
268 | | - | |
269 | | - | |
270 | | - | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
271 | 288 | | |
272 | | - | |
273 | 289 | | |
274 | 290 | | |
275 | 291 | | |
| |||
376 | 392 | | |
377 | 393 | | |
378 | 394 | | |
379 | | - | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
380 | 400 | | |
381 | 401 | | |
382 | 402 | | |
| |||
391 | 411 | | |
392 | 412 | | |
393 | 413 | | |
394 | | - | |
395 | | - | |
| 414 | + | |
| 415 | + | |
396 | 416 | | |
397 | 417 | | |
398 | 418 | | |
| |||
412 | 432 | | |
413 | 433 | | |
414 | 434 | | |
| 435 | + | |
415 | 436 | | |
416 | 437 | | |
417 | 438 | | |
| |||
421 | 442 | | |
422 | 443 | | |
423 | 444 | | |
| 445 | + | |
424 | 446 | | |
425 | 447 | | |
426 | 448 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
| 38 | + | |
37 | 39 | | |
38 | 40 | | |
39 | 41 | | |
| |||
66 | 68 | | |
67 | 69 | | |
68 | 70 | | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
69 | 87 | | |
70 | 88 | | |
71 | 89 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
9 | 13 | | |
10 | 14 | | |
11 | 15 | | |
| |||
0 commit comments