Skip to content

Commit 3333046

Browse files
committed
feat: add one time job
1 parent b347c9b commit 3333046

File tree

11 files changed

+1879
-76
lines changed

11 files changed

+1879
-76
lines changed

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,15 @@ name = "async_simple"
3333
path = "examples/async_simple.rs"
3434
required-features = ["async"]
3535

36+
[[example]]
37+
name = "one_time_execution"
38+
path = "examples/one_time_execution.rs"
39+
required-features = ["sync"]
40+
41+
[[example]]
42+
name = "async_one_time_execution"
43+
path = "examples/async_one_time_execution.rs"
44+
required-features = ["async"]
45+
3646
[package.metadata.docs.rs]
3747
features = ["async", "sync"]

README.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ A lightweight, thread-safe cron job scheduler for Rust with support for both syn
1313
-**Sync & Async** - Choose the execution mode that fits your application
1414
- 🌍 **Timezone Aware** - Full timezone support via chrono
1515
- 🎯 **Second Precision** - 7-field cron expressions with second-level scheduling
16+
-**One-Time Execution** - Schedule tasks to run once at a specific time or after a delay
1617
- 🔧 **Runtime Control** - Add, remove, start, and stop jobs dynamically
1718
- 🛡️ **Thread Safe** - Built with Rust's safety guarantees
1819

@@ -99,6 +100,61 @@ sec min hour day month weekday year
99100

100101
## Advanced Examples
101102

103+
### One-Time Execution
104+
105+
Schedule tasks to run exactly once at a specific time or after a delay:
106+
107+
```rust
108+
use chrono::{Duration, Utc};
109+
use cron_tab::Cron;
110+
111+
fn main() {
112+
let mut cron = Cron::new(Utc);
113+
114+
// Execute once after a delay
115+
cron.add_fn_after(std::time::Duration::from_secs(5), || {
116+
println!("This runs once after 5 seconds");
117+
}).unwrap();
118+
119+
// Execute once at a specific datetime
120+
let target_time = Utc::now() + Duration::seconds(10);
121+
cron.add_fn_once(target_time, || {
122+
println!("This runs once at the specified time");
123+
}).unwrap();
124+
125+
cron.start();
126+
std::thread::sleep(std::time::Duration::from_secs(12));
127+
cron.stop();
128+
}
129+
```
130+
131+
### Async One-Time Execution
132+
133+
```rust
134+
use chrono::{Duration, Utc};
135+
use cron_tab::AsyncCron;
136+
137+
#[tokio::main]
138+
async fn main() {
139+
let mut cron = AsyncCron::new(Utc);
140+
141+
// Execute once after a delay
142+
cron.add_fn_after(std::time::Duration::from_secs(5), || async {
143+
println!("Async task runs once after 5 seconds");
144+
}).await.unwrap();
145+
146+
// Execute once at a specific datetime
147+
let target_time = Utc::now() + Duration::seconds(10);
148+
cron.add_fn_once(target_time, || async {
149+
println!("Async task runs once at the specified time");
150+
}).await.unwrap();
151+
152+
cron.start().await;
153+
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
154+
cron.stop().await;
155+
}
156+
```
157+
102158
### Managing Jobs Dynamically
103159

104160
```rust
@@ -118,7 +174,7 @@ fn main() {
118174

119175
// Remove the job dynamically
120176
cron.remove(job_id);
121-
177+
122178
cron.stop();
123179
}
124180
```
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//! Example demonstrating async one-time task execution at a specific time or after a delay.
2+
//!
3+
//! This example shows how to use the `add_fn_once` and `add_fn_after` methods
4+
//! with async functions to schedule tasks that execute exactly once.
5+
6+
use chrono::{Duration, Utc};
7+
use cron_tab::AsyncCron;
8+
use std::sync::Arc;
9+
use tokio::sync::Mutex;
10+
11+
#[tokio::main]
12+
async fn main() {
13+
println!("=== Async One-Time Task Execution Example ===\n");
14+
15+
let mut cron = AsyncCron::new(Utc);
16+
17+
// Shared counter to track execution
18+
let counter = Arc::new(Mutex::new(0));
19+
20+
// Example 1: Execute once after a delay
21+
println!("Scheduling async job to execute after 2 seconds...");
22+
let counter1 = Arc::clone(&counter);
23+
cron.add_fn_after(std::time::Duration::from_secs(2), move || {
24+
let counter = Arc::clone(&counter1);
25+
async move {
26+
let mut count = counter.lock().await;
27+
*count += 1;
28+
println!("[After 2s] Async job executed! Counter: {}", *count);
29+
30+
// Simulate async work
31+
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
32+
}
33+
})
34+
.await
35+
.unwrap();
36+
37+
// Example 2: Execute once at a specific datetime
38+
let target_time = Utc::now() + Duration::seconds(4);
39+
println!(
40+
"Scheduling async job to execute at specific time: {}",
41+
target_time.format("%H:%M:%S")
42+
);
43+
let counter2 = Arc::clone(&counter);
44+
cron.add_fn_once(target_time, move || {
45+
let counter = Arc::clone(&counter2);
46+
async move {
47+
let mut count = counter.lock().await;
48+
*count += 10;
49+
println!(
50+
"[At {}] Async job executed! Counter: {}",
51+
target_time.format("%H:%M:%S"),
52+
*count
53+
);
54+
55+
// Simulate async work
56+
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
57+
}
58+
})
59+
.await
60+
.unwrap();
61+
62+
// Example 3: Execute once after 6 seconds
63+
println!("Scheduling async job to execute after 6 seconds...");
64+
let counter3 = Arc::clone(&counter);
65+
cron.add_fn_after(std::time::Duration::from_secs(6), move || {
66+
let counter = Arc::clone(&counter3);
67+
async move {
68+
let mut count = counter.lock().await;
69+
*count += 100;
70+
println!("[After 6s] Async job executed! Counter: {}", *count);
71+
72+
// Simulate async work
73+
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
74+
}
75+
})
76+
.await
77+
.unwrap();
78+
79+
// Example 4: Mix with recurring job
80+
println!("Scheduling recurring async job every 3 seconds...");
81+
let recurring_counter = Arc::new(Mutex::new(0));
82+
let recurring_counter1 = Arc::clone(&recurring_counter);
83+
cron.add_fn("*/3 * * * * * *", move || {
84+
let counter = Arc::clone(&recurring_counter1);
85+
async move {
86+
let mut count = counter.lock().await;
87+
*count += 1;
88+
println!("[Recurring] Executed {} times", *count);
89+
90+
// Simulate async work
91+
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
92+
}
93+
})
94+
.await
95+
.unwrap();
96+
97+
// Start the scheduler
98+
println!("\nStarting scheduler...\n");
99+
cron.start().await;
100+
101+
// Let it run for 8 seconds
102+
tokio::time::sleep(std::time::Duration::from_secs(8)).await;
103+
104+
// Stop the scheduler
105+
cron.stop().await;
106+
107+
println!("\n=== Execution Complete ===");
108+
println!("Final one-time counter: {}", *counter.lock().await);
109+
println!(
110+
"Final recurring counter: {}",
111+
*recurring_counter.lock().await
112+
);
113+
println!("\nNote: One-time jobs execute exactly once and are automatically removed.");
114+
}

examples/one_time_execution.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//! Example demonstrating one-time task execution at a specific time or after a delay.
2+
//!
3+
//! This example shows how to use the `add_fn_once` and `add_fn_after` methods
4+
//! to schedule tasks that execute exactly once.
5+
6+
use chrono::{Duration, Utc};
7+
use cron_tab::Cron;
8+
use std::sync::{Arc, Mutex};
9+
10+
fn main() {
11+
println!("=== One-Time Task Execution Example ===\n");
12+
13+
let mut cron = Cron::new(Utc);
14+
15+
// Shared counter to track execution
16+
let counter = Arc::new(Mutex::new(0));
17+
18+
// Example 1: Execute once after a delay
19+
println!("Scheduling job to execute after 2 seconds...");
20+
let counter1 = Arc::clone(&counter);
21+
cron.add_fn_after(std::time::Duration::from_secs(2), move || {
22+
let mut count = counter1.lock().unwrap();
23+
*count += 1;
24+
println!("[After 2s] Job executed! Counter: {}", *count);
25+
})
26+
.unwrap();
27+
28+
// Example 2: Execute once at a specific datetime
29+
let target_time = Utc::now() + Duration::seconds(4);
30+
println!(
31+
"Scheduling job to execute at specific time: {}",
32+
target_time.format("%H:%M:%S")
33+
);
34+
let counter2 = Arc::clone(&counter);
35+
cron.add_fn_once(target_time, move || {
36+
let mut count = counter2.lock().unwrap();
37+
*count += 10;
38+
println!("[At {}] Job executed! Counter: {}", target_time.format("%H:%M:%S"), *count);
39+
})
40+
.unwrap();
41+
42+
// Example 3: Execute once after 6 seconds
43+
println!("Scheduling job to execute after 6 seconds...");
44+
let counter3 = Arc::clone(&counter);
45+
cron.add_fn_after(std::time::Duration::from_secs(6), move || {
46+
let mut count = counter3.lock().unwrap();
47+
*count += 100;
48+
println!("[After 6s] Job executed! Counter: {}", *count);
49+
})
50+
.unwrap();
51+
52+
// Example 4: Mix with recurring job
53+
println!("Scheduling recurring job every 3 seconds...");
54+
let recurring_counter = Arc::new(Mutex::new(0));
55+
let recurring_counter1 = Arc::clone(&recurring_counter);
56+
cron.add_fn("*/3 * * * * * *", move || {
57+
let mut count = recurring_counter1.lock().unwrap();
58+
*count += 1;
59+
println!("[Recurring] Executed {} times", *count);
60+
})
61+
.unwrap();
62+
63+
// Start the scheduler
64+
println!("\nStarting scheduler...\n");
65+
cron.start();
66+
67+
// Let it run for 8 seconds
68+
std::thread::sleep(std::time::Duration::from_secs(8));
69+
70+
// Stop the scheduler
71+
cron.stop();
72+
73+
println!("\n=== Execution Complete ===");
74+
println!("Final one-time counter: {}", *counter.lock().unwrap());
75+
println!("Final recurring counter: {}", *recurring_counter.lock().unwrap());
76+
println!("\nNote: One-time jobs execute exactly once and are automatically removed.");
77+
}

0 commit comments

Comments
 (0)