Skip to content

Commit 3084b2e

Browse files
authored
Merge pull request #98 from dev-five-git/impl-cron
Impl cron
2 parents 093d95f + 4f58312 commit 3084b2e

16 files changed

Lines changed: 806 additions & 117 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes":{"Cargo.toml":"Patch"},"note":"Impl cron","date":"2026-03-17T12:10:44.999667200Z"}

Cargo.lock

Lines changed: 43 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,65 @@ let summary: vespera::schema::Schema = schema!(User, pick = ["id", "name"]);
511511
512512
---
513513

514+
## Cron Jobs
515+
516+
Schedule background tasks with `#[vespera::cron]`. Uses [tokio-cron-scheduler](https://crates.io/crates/tokio-cron-scheduler) under the hood.
517+
518+
### Enable Feature
519+
520+
```toml
521+
[dependencies]
522+
vespera = { version = "0.1", features = ["cron"] }
523+
```
524+
525+
### Define Cron Jobs
526+
527+
Place `#[vespera::cron("...")]` on any `pub async fn` with zero parameters. The function can live anywhere in your project — no special directory required.
528+
529+
```rust
530+
// src/cron/cleanup.rs, src/tasks.rs, or even src/routes/users.rs — anywhere works
531+
#[vespera::cron("1/10 * * * * *")]
532+
pub async fn cleanup_sessions() {
533+
println!("Running cleanup every 10 seconds");
534+
}
535+
536+
#[vespera::cron("0 0 * * * *")]
537+
pub async fn hourly_report() {
538+
println!("Running hourly report");
539+
}
540+
```
541+
542+
### How It Works
543+
544+
1. `#[cron("...")]` registers the job at compile time (like `#[route]`)
545+
2. `vespera!()` auto-discovers all registered cron jobs — no extra parameters needed
546+
3. A background scheduler spawns via `tokio::spawn` when the app starts
547+
548+
```rust
549+
// No cron-specific config — just works
550+
let app = vespera!(docs_url = "/docs");
551+
```
552+
553+
### Cron Expression Format
554+
555+
Uses 6-field cron expressions (`sec min hour day month weekday`):
556+
557+
| Expression | Schedule |
558+
|-----------|----------|
559+
| `0 */5 * * * *` | Every 5 minutes |
560+
| `0 0 * * * *` | Every hour |
561+
| `0 0 0 * * *` | Daily at midnight |
562+
| `1/10 * * * * *` | Every 10 seconds |
563+
| `0 30 9 * * Mon-Fri` | Weekdays at 9:30 AM |
564+
565+
### Requirements
566+
567+
- Functions must be `pub async fn`
568+
- Functions must take **no parameters** (no `State`, no extractors)
569+
- The `cron` feature must be enabled
570+
571+
---
572+
514573
## Advanced Usage
515574

516575
### Adding State

crates/vespera/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ repository.workspace = true
88

99
[features]
1010
default = ["axum-extra/typed-header", "axum-extra/form", "axum-extra/query", "axum-extra/multipart", "axum-extra/cookie"]
11+
cron = ["dep:tokio-cron-scheduler", "dep:tokio"]
1112

1213
[dependencies]
1314
vespera_core = { workspace = true }
@@ -19,6 +20,8 @@ tempfile = "3"
1920
serde_json = "1"
2021
tower-layer = "0.3"
2122
tower-service = "0.3"
23+
tokio-cron-scheduler = { version = "0.13", optional = true }
24+
tokio = { version = "1", features = ["rt"], optional = true }
2225

2326
[lints]
2427
workspace = true

crates/vespera/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub mod openapi {
2020
pub use vespera_core::openapi::OpenApi;
2121

2222
// Re-export macros from vespera_macro
23-
pub use vespera_macro::{Multipart, Schema, export_app, route, schema, schema_type, vespera};
23+
pub use vespera_macro::{Multipart, Schema, cron, export_app, route, schema, schema_type, vespera};
2424

2525
// Re-export serde_json for merge feature (runtime spec merging)
2626
pub use serde_json;
@@ -35,6 +35,14 @@ pub mod multipart;
3535
// Re-export tempfile for schema_type! multipart mode (NamedTempFile)
3636
pub use tempfile;
3737

38+
// Re-export tokio-cron-scheduler for cron job support
39+
#[cfg(feature = "cron")]
40+
pub use tokio_cron_scheduler;
41+
42+
// Re-export tokio for cron scheduler spawning
43+
#[cfg(feature = "cron")]
44+
pub use tokio;
45+
3846
// Re-export axum for convenience
3947
pub mod axum {
4048
pub use axum::*;

0 commit comments

Comments
 (0)