deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Cronflower turns Spring Boot apps into distributed cron and DAG workflow clusters

Open-source project Cronflower pairs a clustered, persistent replacement for Spring Boot's @Scheduled with a DAG workflow engine, adding retries, timeouts and a web console without an external broker or database.

Cronflower turns Spring Boot apps into distributed cron and DAG workflow clusters

Two posts, one project

According to two announcement posts published on dev.to, an open-source project called Cronflower targets a familiar Spring Boot pain point: @Scheduled runs inside a single JVM, so scaling to a second instance makes the job fire twice, and the built-in scheduler offers no retries, no timeouts and no record of what ran. Teams typically patch this with Quartz, a database, a lock table and a hand-built dashboard. Cronflower packages that entire stack — and the posts appear to come from the project's own developer, so claims are not yet independently verified.

The project has two halves: cronsmith, a distributed task scheduler, and cronflow, a DAG workflow orchestrator. Both share one cluster and one web console, and the system forms its own cluster with no external database, broker or coordinator required. The persistence store is auto-detected from the application's datasource: in-memory with no database, or H2, SQLite, MySQL or PostgreSQL when one is configured.

Distributed scheduling with cronsmith

The architecture splits into two roles. Scheduler processes own the schedules, hold task state and elect a leader over gossip; executors are your application JVMs, which declare tasks as @Task-annotated bean methods and run the code when dispatched. Executors register and heartbeat so the scheduler always knows where code can run.

Schedules can be expressed as cron expressions, fixed intervals, ISO-8601 durations for gaps cron cannot span, or a year-based variant called YCRON for dates like "noon on the 200th day". Task parameters may be constants or SpEL templates evaluated fresh on each fire.

The operational awkwardness lives in annotation attributes rather than custom code: maxRetryCount and retryInterval for retries with logged attempts, a per-run timeout to catch hung jobs, a misfire policy (skip, fire once now, or fire all missed runs) for downtime recovery, and repeatCount or stopAt for bounded tasks. Jobs that merely call a URL need no executor at all — HTTP tasks run on the scheduler node and can be created or edited from the console or REST API without a redeploy.

Storage mode matters for scale. With node-local H2 or SQLite stores, the leader keeps nodes in sync; a shared MySQL or PostgreSQL database additionally enables group sharding, where each node fires only the task groups that hash to it.

DAG workflows with cronflow

The second dev.to post addresses chained cron jobs: one job at 02:00, another at 02:15 because that is usually long enough. Cronflow replaces the clock-based coupling with declared graphs. A workflow is a Spring bean: @Dag names it, @DagNode methods are steps, and edge lists define the shape.

Data moves between nodes through named channels, and each channel declares a reducer — sum, max, boolean folds, list or map merges, join-CSV, last-wins and more, with custom reducer beans also supported. Concurrent writes to the same channel are merged automatically, which the author presents as eliminating the races and locks you would write by hand.

Control flow covers conditional routing via SpEL expressions, ALL and ANY join modes, subgraphs that embed one DAG as a node in another, and @Shard for run-time fan-out that runs a step once per item in a list. Workflows can be triggered manually from the console, kicked off by a scheduled task whose return value seeds the input, or scheduled directly as a trigger-DAG task type. Because the engine dispatches nodes to live executors across the cluster, a wide fan-out runs genuinely in parallel, and each run's view shows which executor handled which node and what it produced.

Getting started

Per the announcement, cloning the repository and running a bundled deploy script brings up a scheduler, console and executor over an embedded store with nothing to provision; command-line flags scale the same setup to multiple schedulers and executors, and a Docker script is provided. The console listens on port 7200, and the bundled executor ships with sample workflows ready to trigger.

Why it matters

Scheduled work is where single-instance assumptions break quietly: jobs fire twice, or not at all, and nobody notices until a nightly rollup is missing. Cronflower's pitch is that fixing this should not require assembling Quartz, a lock table, a broker and a homemade dashboard. By folding retries, timeouts, misfire handling, execution history, leader election and DAG orchestration into annotations on ordinary Spring beans — with no mandatory external infrastructure — it lowers the barrier between "an app with a cron job" and "a workflow platform". The obvious caveat is that both sources are launch posts by the project's author; exactly-once firing and failover behaviour will need scrutiny from independent production use.

  • #spring-boot
  • #scheduling
  • #workflow
  • #distributed-systems
  • #open-source

Related posts