Quick Start
How It Works
The AsyncAgentScheduler uses async-native execution with cooperative cancellation, replacing the old thread-based scheduler.The scheduler’s async primitives (
_stop_event, _cancel_event, _stats_lock) are now created lazily inside _ensure_async_primitives() and bound to the loop that start() runs on. Tests that call stop() without first calling start() must invoke scheduler._ensure_async_primitives() explicitly — see tests/unit/scheduler/test_async_agent_scheduler.py in PR #1583 for the canonical pattern.Schedule Expression Reference
| Expression | Interval | Description |
|---|---|---|
"daily" | 86400s | Every 24 hours |
"hourly" | 3600s | Every hour |
"*/30m" | 1800s | Every 30 minutes |
"*/1h" | 3600s | Every 1 hour |
"*/5s" | 5s | Every 5 seconds |
"60" | 60s | Custom seconds (plain digits) |
Configuration Options
AsyncAgentScheduler Constructor
| Parameter | Type | Default | Description |
|---|---|---|---|
agent | Any | Required | Agent instance to schedule |
task | str | Required | Task description to execute |
config | Optional[Dict[str, Any]] | None | Optional configuration dictionary |
on_success | Optional[Callable[[Any], None]] | None | Callback function on successful execution |
on_failure | Optional[Callable[[Exception], None]] | None | Callback function on failed execution |
start() Method Options
| Parameter | Type | Default | Description |
|---|---|---|---|
schedule_expr | str | Required | Schedule expression (e.g., “hourly”, ”*/1h”, “3600”) |
max_retries | int | 3 | Maximum retry attempts on failure |
run_immediately | bool | False | If True, run agent immediately before starting schedule |
Reading Stats
Statistics can be read in both sync and async contexts with different guarantees:| Method | Sync/Async | Atomicity | When to Use |
|---|---|---|---|
get_stats() | sync | Best-effort, NOT atomic — counters may be observed mid-update | Quick sync checks, tests, scripts |
get_stats_sync() | sync | Alias for get_stats() (same best-effort behaviour, named for clarity) | When you want the sync intent obvious in code |
get_stats_async() | async | Atomic snapshot under _stats_lock | Inside async code paths where consistency matters |
Stats Response Format
| Field | Type | Description |
|---|---|---|
is_running | bool | Whether scheduler is currently running |
total_executions | int | Total number of execution attempts |
successful_executions | int | Number of successful executions |
failed_executions | int | Number of failed executions |
success_rate | float | Success percentage (0-100) |
Common Patterns
Running in FastAPI Application
Error Handling with Logging
Graceful Shutdown on SIGINT
Best Practices
Always await scheduler.stop() before exiting
Always await scheduler.stop() before exiting
The
stop() method waits up to 30 seconds for the current execution to complete before canceling. This prevents data corruption and ensures clean shutdown.Use run_immediately=True for testing
Use run_immediately=True for testing
Enable
run_immediately=True to verify your agent works correctly before waiting for the first scheduled interval.Keep callbacks lightweight
Keep callbacks lightweight
Success and failure callbacks are called synchronously. Heavy operations should be offloaded to avoid blocking the scheduler.
Prefer AsyncAgentScheduler over legacy thread-based scheduler
Prefer AsyncAgentScheduler over legacy thread-based scheduler
For new code, use
AsyncAgentScheduler instead of the legacy AgentScheduler. The async version provides better cancellation, no daemon threads, and fits naturally into async applications.Import paths (updated in PR #1723):
- Canonical (recommended):
from praisonai.scheduler import AsyncAgentScheduler - Explicit module path:
from praisonai.scheduler.async_agent_scheduler import AsyncAgentScheduler - Deprecated (still works, emits
DeprecationWarning):from praisonai.async_agent_scheduler import AsyncAgentScheduler
AgentScheduler is unchanged: from praisonai.scheduler import AgentScheduler.Related
Scheduler CLI
Command-line interface for scheduling agents
Background Tasks
Running agents as background processes

