Clokwerk
Schedule recurring tasks in Rust with a readable DSL instead of cron strings.
Repository Health
Technical Analysis
Clokwerk is a simple recurring task scheduler for Rust, inspired by Python’s schedule and Ruby’s clockwork. Rather than parsing cron strings, it uses a fluent DSL to express intervals such as every ten minutes or every Tuesday at a set time. It supports timezone-aware scheduling and, since version 0.4, includes a separate AsyncScheduler for running asynchronous tasks concurrently.
What You Get
- A
Schedulerwith a fluentevery(...).at(...).run(...)DSL for recurring jobs - An
AsyncSchedulerfor running async tasks concurrently on a runtime - Timezone-aware scheduling through
Scheduler::with_tz - Background execution via
watch_threadwith a stoppable handle - Interval helpers like
10.minutes()and weekday constants for readable schedules
Common Use Cases
- Running periodic maintenance or cleanup jobs inside a long-lived Rust service
- Triggering daily or weekly tasks at specific local or fixed-timezone times
- Scheduling concurrent async background work without pulling in a cron parser
Under The Hood
Architecture
Scheduling is built from src/scheduler.rs and src/async_scheduler.rs, which hold collections of jobs and decide which are due, while src/job.rs, src/sync_job.rs, and src/async_job.rs model individual tasks and their run closures. src/intervals.rs and src/job_schedule.rs implement the fluent interval DSL and the logic that computes each job’s next execution, and src/timeprovider.rs abstracts the clock so timing is testable.
Tech Stack
It targets Rust edition 2018 and depends on chrono for timezone-aware date and time math, with an async feature (enabled by default) gating the AsyncScheduler. Dev dependencies include tokio, async-std, tokio-test, and once_cell to exercise both sync and async paths across runtimes.
Code Quality
Inline #[test] modules appear across intervals.rs, job_schedule.rs, and scheduler.rs, and the timeprovider abstraction lets tests drive deterministic virtual clocks rather than sleeping. The separation between interval computation, job storage, and execution keeps the code approachable and well factored.
API Design
The builder DSL, with helpers like 10.minutes() and every(...).at(...).run(...), reads almost like prose and avoids cron syntax entirely. The README demonstrates manual loops, background threads, timezone configuration, and the async scheduler, making common patterns easy to copy. The main learning curve is understanding that you must pump run_pending or use a watch thread.