feat(triggers): Activepieces polling triggers — poll loop, sidecar protocol, CRUD#68
Merged
Merged
Conversation
…otocol, CRUD
Adds polling-based triggers for ActivePieces pieces: a tenant-scoped
trigger registration (trigger_type: activepieces_poll) whose config names
a piece, a piece trigger, auth/props (credentials:// resolved per poll),
and a schedule (interval_secs or cron). The engine's trigger sync loop
spawns a poll listener per registration that asks the Node sidecar's new
POST /poll endpoint to run the piece trigger headlessly; each returned
item creates one durable instance, and the trigger's store contents are
persisted as an opaque dedupe cursor (trigger_poll_state table) and sent
back on the next poll. Failed polls record last_error and bump
consecutive_failures (surfaced on GET /triggers/{slug}) without ever
stopping the loop.
- orch8-types: TriggerType::ActivepiecesPoll + TriggerPollState
- orch8-storage: trigger_poll_state table (migration 044 + sqlite schema),
get/upsert poll-state on AdminStore (sqlite, postgres, encrypting)
- orch8-engine: ap_poll module (config parsing, poll loop, failure
bookkeeping), trigger sync wiring, cron::next_fire_from_expr, metrics
- orch8-api: config validation on create, poll_state on GET, OpenAPI
- sidecar: POST /poll op, findTrigger, buildTriggerContext with seeded
store; webhook-strategy triggers rejected as permanent
- tests: engine poll loop vs dep-free TCP mock sidecar, API CRUD/tenant
isolation, storage round-trips, sidecar stub-piece polling suite
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Item #8 from docs/FEATURE_OPPORTUNITIES.md: event-driven workflows from the Activepieces catalog — "when a Stripe payment fails → start a durable sequence." Polling-based per the doc's explicit scoping (webhook triggers deliberately deferred).
TriggerType::ActivepiecesPollrides the existing triggers table + 15s sync loop (same listener model as NATS/file-watch). Config:piece,trigger,auth,props,interval_secsXORcron(default 60s, 1s floor).POST /poll(same envelope as/execute): loads the piece, seeds aTriggerContext.storefrom the opaque cursor, callstrigger.run(), returns{items, state}— matching AP'spollingHelpercontract so real pieces dedupe correctly without the AP platform DB. Webhook-strategy triggers rejected 422.credentials://resolved on every poll (rotation-safe), one instance per item via the same path asPOST /triggers/{slug}/fire, cursor persisted only after all items create instances (at-least-once). Failures:last_error+consecutive_failureson a separatetrigger_poll_staterow (no lost-update race with API edits), loop never exits, metricsorch8_ap_poll_{items,errors}_total.044_trigger_poll_state.sql+ sqlite schema; both backends + encrypting wrapper;GET /triggers/{slug}surfacespoll_state; create validates poll configs (400 with reason).activepieces/README.mddocuments the feature.What's real vs stubbed
The full mechanism is end-to-end real; tests use stub pieces. A real piece needs only
npm install @activepieces/piece-<name>into the sidecar — same operational story as actions today.Tests
14 engine (dep-free TCP mock sidecar: items→instances, cursor round-trip, failure bookkeeping, credential resolution, loop survival), 6 API integration, storage round-trips, 17 sidecar tests (155 total, tsc clean).
cargo testacross 4 crates: 3224 passed. fmt/clippy/doc gates clean.🤖 Generated with Claude Code