ClockMonster
ClockMonster copied to clipboard
distributed advanced cron for distributed systems
ClockMonster
ClockMonster is a self-hosted service for scheduling one-time or repeating jobs within your system. Jobs for now are HTTP POST requests, however in the future will be adding to queues, calling gRPC and more.
This service solves the issue of repeating implementations per-service for time-based events. A simple example of where ClockMonster can come in useful is that your application allows users to create a schedule of times, and you want to get a call to a service when one of the schedule periods start / end.
Note however, ClockMonster is not per-second accurate. You can configure how often you'd like ClockMonster to
poll for tasks via the environment variable EXECUTOR_WAIT_SECONDS
.
By the time of first full release, ClockMonster will be able to be replicated. However, right now if you do so, there is a chance that jobs will get ran twice if their executors line up. To solve this, a job locking system will be added.
ClockMonster supports storing data in either Postgres or Redis. In the future, more databases will be added.
You can select the storage method by the environment variable JOB_STORAGE_METHOD
(see below).
Storage Method Notes
- Postgres
- Will create some tables that ClockMonster will manage.
- To execute, ClockMonster will run a simple query looking for all jobs in the past
- Redis
- Uses scored sets, where the score is the execution time. Value is the job id. Then utilises
zrangebyscore
to order the jobs that are in the past. - Currently, stores the actual job payloads in a different key. The lua script will use
mget
to grab them all at once for jobs that require executing. - Due to the separation of jobs in keys and their scores in the set, as much of the grouped Redis logic as possible is within Lua scripts
- Uses scored sets, where the score is the execution time. Value is the job id. Then utilises
API documentation
Coming soon. Currently there is a work-in-progress TypeScript API in this repository, but it's not finished yet.
ClockMonster has REST API endpoints to interact with it. There will be documentation for these too soon, so you can
implement ClockMonster into a different language, or directly into your system.
How to run ClockMonster
Get it from Docker Hub: https://hub.docker.com/r/hiett/clockmonster
docker pull hiett/clockmonster
Environment variables:
JOB_STORAGE_METHOD
(must be either POSTGRES
or REDIS
)
DB_HOST
(DB configuration only required if JOB_STORAGE_METHOD
=POSTGRES
)
DB_PORT
DB_USERNAME
DB_PASSWORD
DB_DATABASE
DB_MIGRATION_TABLE
(optional)
REDIS_CONN_URL
(Redis configuration only required if JOB_STORAGE_METHOD
=REDIS
)
EXECUTOR_WAIT_SECONDS
(default 5)
Developing ClockMonster
To spin up a Postgres instance for testing with this service:
docker run --name clockmonster-postgres -p 5432:5432 -it -e POSTGRES_PASSWORD=clocks -d postgres
To build docker image from this dir:
cd clockmonster
./mvnw package -Pnative -Dquarkus.native.container-build=true
docker build -f src/main/docker/Dockerfile.native-distroless -t hiett/clockmonster .
Make sure to have GraalVM installed with native-image from gu.