Async & Scheduled Tasks
StackRivet separates two things that look similar but have different boundaries:
- Async tasks — “submit and run” heavy work: imports, exports, code-generation writes, asset processing. The concern is a state machine, idempotency, cancel, retry, timeout and error categories.
- Scheduled tasks — cron / fixed-rate work: visual task management, cluster de-duplication, manual trigger, retry, alerts and audit.
Async tasks
Section titled “Async tasks”Heavy work never blocks a request thread. It is submitted as a task and tracked through a state machine:
stateDiagram-v2 [*] --> pending pending --> running pending --> cancelled running --> success running --> failed failed --> retrying retrying --> running running --> cancelled success --> [*] cancelled --> [*]
Each task carries an idempotencyKey so a retry doesn’t run the work twice, plus retry, cancel, timeout and an error category. The stackrivet-task module owns this machine, and the admin UI ships a /tasks page to filter, submit, run, cancel, retry and inspect tasks.
This is why imports, exports and generator writes are listed as async work in the Architecture — a 50 MB import or a large export must not hold a web thread.
Scheduled tasks: a framework-agnostic SPI
Section titled “Scheduled tasks: a framework-agnostic SPI”Scheduling is decoupled from any specific scheduler framework. The stackrivet-task module defines a small Scheduler SPI — ScheduledJobHandler, ScheduledJobContext, ScheduledJobResult, ScheduledJobRegistry, SchedulerAdapter, SchedulerCapability — and a business job depends only on these StackRivet interfaces, never on a third-party scheduler’s API.
The default release embeds only StackRivet’s own scheduling abstraction plus a local scheduler bridge that dispatches jobs by handler name (and restores the tenant context at the execution boundary). There is no GPL component in the default runtime — an earlier XXL-Job experiment was reverted precisely because XXL-Job is GPL-3.0 and StackRivet is Apache-2.0 with a commercial Enterprise tier.
SnailJob as the enterprise adapter
Section titled “SnailJob as the enterprise adapter”For distributed scheduling, SnailJob (Apache-2.0) is the priority adapter, shipped as an optional module (stackrivet-scheduler-snailjob). It is:
- Activated only when
stackrivet.scheduler.snailjob.enabled=true— even if the jar is on the classpath it stays dormant by default. - Kept out of the base runtime:
stackrivet-appdoes not depend on it, so the default dependency tree has zero scheduler-framework code. - A bridge that maps SnailJob’s callbacks onto the same
SchedulerAdapterSPI, adding distributed retry, replay governance, alerts and a console.
PowerJob (complex DAG / MapReduce) and ElasticJob (existing ZooKeeper users) are available as further optional adapters; XXL-Job is documented for migration/external triggering only and is never a StackRivet dependency.
Edition boundary
Section titled “Edition boundary”The Scheduler SPI, local task examples and the /tasks admin page are in Community. The SnailJob adapter and distributed retry / replay governance are Pro / Enterprise — see the pricing page. Because the SPI is in Community, your job code is written against StackRivet interfaces from day one and gains distributed scheduling later without changes.