Commit 5485192
feat: backfill — re-run a watch action over the previous step's passes (#163)
Adds `magpie backfill`: queue a re-run of one action over the feed items the
PREVIOUS step passed (or, for a chain-head target, the watch's feed items in a
window), so its output can be regenerated after a config change (e.g. an `extract`
action's field set changed) without waiting for new items.
Design:
- Async job, off the request path. POST /v1/actions/<id>/backfill writes a PENDING
WatchActionBackfill row and returns fast; a new `process_due_backfills` cron
(stage 1b, before the drain) claims it, does the select/delete/enqueue, marks it
terminal; the existing `process_due_runs` drain executes the enqueued runs and
`enqueue_next` advances the chain.
- Additive by default (fill only never-processed items); `--replace` regenerates the
WHOLE chain from the target down (deletes the target's + every downstream action's
terminal runs for the matched items, then re-enqueues the target; downstream
refills as the chain advances). The idempotent enqueue is what re-creates the
deleted runs, so the delete IS the replace.
- Crash-recovery mirrors the run drain: guarded-CAS claim/reap/terminal-write, a
`replace_deleted_at` delete-once marker stamped before enqueue (a retried job never
re-deletes drain-regenerated runs), FAILED transient-until-exhausted (retryable
while completed_at is unset, terminal once set).
- Memory: the source set is never materialized. Explicit service methods return
definitive objects off one private queryset builder per source — a count (int), a
Subquery (the `feed_item_id__in` operand for the server-side delete + preview
counts), and a keyset iterator (the enqueue stream, pooler-safe unlike a
server-side cursor). Preview and executor share resolve_present + chain_from +
the terminal predicate so their counts can't drift.
CLI: `magpie backfill submit --action <id> <window> [--replace]` / `status <id>` /
`list` — a flat top-level noun like `activity`/`delivery` (submit scopes the action
via --action; status/list address the job by its own id). `--dry-run` shows a
read-only size preview; an interactive submit previews + confirms; a piped submit
requires --yes (a pipe can't silently enqueue LLM-cost work). Window is required
(no all-retention default).
Wire contract in openmagpie-schema (BackfillPreview / BackfillJob /
BackfillListResponse + WatchActionBackfillState); `replace` coerced via a DRF
BooleanField (parser-agnostic; the JSON/form string "false" can't trigger the
destructive delete). Routes parent-qualified: /v1/action-backfills[/<id>] (list +
status), submit at /v1/actions/<id>/backfill. process_due_backfills wired into the
tick before the drain (+ down-jobs). Docs in apps/core + apps/cli AGENTS.md.
Tested: core endpoint/operation/Global suites (additive, replace-whole-chain,
delete-once under reap+retry, chain-head source, >page keyset enqueue in autocommit,
string-bool coercion) + CLI suite (validation, wiring, dry-run guard, pipe gate,
confirm accept/decline). Verified end to end live against a real extract action.
Claude-Session: https://claude.ai/code/session_01Xe6qZzz7jCaAhURhD8vmux
Co-authored-by: Josh Panka <josh.panka@obris.io>1 parent c4efb3a commit 5485192
42 files changed
Lines changed: 2750 additions & 60 deletions
File tree
- apps
- cli
- src/openmagpie
- api
- commands
- watch
- tests
- core
- conf
- settings
- feeds/services/feeds
- watches
- management/commands
- migrations
- models
- operations
- services
- runs
- watches
- make
- packages/openmagpie-schema
- src/openmagpie_schema
- scripts/quickstart
- tools/schema_sync
- web/packages/schema/src
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
44 | | - | |
| 44 | + | |
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
75 | | - | |
| 75 | + | |
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
30 | 34 | | |
31 | 35 | | |
32 | 36 | | |
| |||
122 | 126 | | |
123 | 127 | | |
124 | 128 | | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
64 | 65 | | |
65 | 66 | | |
66 | 67 | | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
67 | 73 | | |
68 | 74 | | |
69 | 75 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| |||
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
| 93 | + | |
93 | 94 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
| 32 | + | |
33 | 33 | | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
45 | 46 | | |
46 | | - | |
| 47 | + | |
47 | 48 | | |
48 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
49 | 69 | | |
50 | 70 | | |
51 | 71 | | |
0 commit comments