Chronos Engine is a powerful, asynchronous, and resilient task scheduling system built with Python. It is designed to handle a large volume of scheduled tasks by leveraging a tiered bucketing strategy with PostgreSQL, a persistent data store with MongoDB, and a high-throughput message queue with Apache Kafka for scalable task execution.
This architecture is event-driven and designed for scalability and fault tolerance, making it suitable for applications that need to reliably execute tasks at specific times.
The lifecycle of a scheduled task (a "campaign") follows this path:
- API Ingestion: A new campaign is scheduled via a
POSTrequest to the FastAPIapiservice. - Data Storage & Bucketing:
- The full campaign details are saved permanently in MongoDB.
- A reference to the task is placed into the appropriate time-based "bucket" in PostgreSQL (
yearly,monthly,weekly,daily, orhourly) based on itsscheduled_fortime.
- Worker Processing: A single, consolidated
workersprocess runs in the background, containing multiple concurrent tasks:- Bucket Workers: Periodically, tasks are moved from long-term buckets to shorter-term buckets as their execution time approaches (e.g., from
daily_buckettohourly_bucket). - Dispatcher & Publisher: When a task is due, it's moved to a
kafka_outboxtable and reliably published as a message to a Kafka topic. This uses the Transactional Outbox pattern for resilience.
- Bucket Workers: Periodically, tasks are moved from long-term buckets to shorter-term buckets as their execution time approaches (e.g., from
- Task Execution:
- A team of scalable
campaign_executorconsumers listens to the Kafka topic. - When a message is received, the consumer fetches the full details from MongoDB and executes the task.
- Kafka's consumer group protocol automatically load balances the tasks among all available consumer instances.
- A team of scalable
Follow these instructions to get the entire application stack running locally.
-
Clone the repository:
git clone [https://github.com/wailbentafat/chronos-engine.git](https://github.com/wailbentafat/chronos-engine.git) cd chronos-engine -
Configuration: All necessary environment variables are pre-configured in the
docker-compose.ymlfile using a YAML anchor (&app-env) for consistency. Key variables include database connection strings and Kafka broker addresses. -
Build and Run the Application: This single command will build your application's Docker image and start all the services (API, workers, databases, Kafka) in the background.
docker-compose up --build -d
On the very first run, the application will automatically:
- Create all the necessary tables and indexes in the PostgreSQL database.
- Create the
campaign_taskstopic in Kafka with 3 partitions for scalability.
-
Check that all services are running:
docker-compose ps
You should see all containers (
api,workers,campaign_executor,postgres,mongo,kafka,zookeeper) with arunningorUpstatus.
To schedule a new task, send a POST request to the /campaigns endpoint.
- Endpoint:
POST /campaigns - Body: A JSON object with
business_id,name, and ascheduled_fortimestamp in ISO 8601 format (UTC is recommended, indicated by aZ).
Example using curl:
This schedules a campaign to run in the near future.
curl -X 'POST' \
'http://localhost:8000/campaigns' \
-H 'Content-Type: application/json' \
-d '{
"business_id": "biz_123_test",
"name": "My First Scheduled Campaign",
"scheduled_for": "2025-06-09T14:30:00Z"
}'