This is a RESTful API for scheduling HTTP requests. It is built using Rust language and Actix framework, backed up with Sled KV store. It is designed to be highly available and scalable. It can be deployed as a single node or a cluster. Cluster is driven by async-raft library. It uses Raft consensus algorithm to replicate the database to all nodes in the cluster. It is also designed to be fault-tolerant. If a node is down, the cluster will still be available and available nodes will take over the down node's responsibilities (to execute schedules). The cluster will be unavailable only if the majority of nodes are down.
The service is under heavy development, below features may not be available until it is done
To create a schedule, send a POST request to /schedule
with the following body:
{
"id": "ec3eee49-f876-4ceb-a112-9dc33251e506",
"request": {
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
},
"schedule": "0 0 1 1 *"
}
The schedule
field is a cron expression. The above example will send a request to
https://example.com
with Content-Type: text/plain
header and Hello world!
body
on every 1st of January at 00:00.
To schedule one time HTTP request, use schedule_at
field with ISO 8601 format:
{
"id": "87a2df69-f049-46e8-8202-b73ebbc54fda",
"request": {
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
},
"schedule_at": "2021-01-01T00:00:00Z"
}
To get all schedules, send a GET request to /schedule
.
[
{
"id": "87a2df69-f049-46e8-8202-b73ebbc54fda",
"request": {
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
},
"schedule_at": "2021-01-01T00:00:00Z",
"status": "scheduled"
},
{
"id": "ec3eee49-f876-4ceb-a112-9dc33251e506",
"request": {
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
},
"schedule": "0 0 1 1 *",
"status": "scheduled"
}
]
To get a schedule, send a GET request to /schedule/{id}
. The id
is the schedule's
ID. Response body will be the schedule's JSON.
{
"id": "ec3eee49-f876-4ceb-a112-9dc33251e506",
"request": {
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
},
"schedule": "0 0 1 1 *",
"status": "scheduled"
}
status can be scheduled
, running
, failed
or done
.
failed
and done
schedules contains additional info about execution.
{
"id": "ec3eee49-f876-4ceb-a112-9dc33251e506",
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
},
"schedule": "0 0 1 1 *",
"status": "failed",
"last_error": "Failed to connect to host",
"executed_at": "2021-01-01T00:00:00Z"
}
or done
{
"id": "ec3eee49-f876-4ceb-a112-9dc33251e506",
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
},
"schedule": "0 0 1 1 *",
"status": "done",
"executed_at": "2021-01-01T00:00:00Z"
}
Once done, the schedule will be deleted automatically from the database when retention policy is met. Default retention policy is 30 days.
To delete a schedule, send a DELETE request to /schedule/{id}
.
To update a schedule, send a PUT request to /schedule/{id}
with the following body:
{
"request": {
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
},
"schedule": "0 0 1 1 *"
}
To get notified when a schedule is executed, you can use callback URL. Callback URL will be sent a POST request with the following body:
{
"id": "ec3eee49-f876-4ceb-a112-9dc33251e506",
"request": {
"url": "https://example.com",
"method": "GET",
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
},
"schedule": "0 0 1 1 *",
"status": "done",
"executed_at": "2021-01-01T00:00:00Z"
}
To set callback URL, send a PUT request to /schedule/{id}/callback
with the following body:
{
"callback": {
"url": "https://example.com/callback",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer token"
}
}
}
Or set callback
field when creating or updating a schedule.
To authenticate API calls, you can use API key. To create an API key, and use it
in each request in X-API-Key
header.
This service uses Sled as its database. It is a simple embedded database written in Rust.
Copy of the database is stored in data
directory. You can change the directory by
setting SCHEDULERS_DB_PATH
environment variable. The database will be replicated
to all schedule-rs nodes in the cluster.
You can configure the service by setting the following environment variables:
SCHEDULERS_DB_PATH
: Path to the database directory. Default:data
SCHEDULERS_RETENTION_POLICY
: Retention policy in days. Default:30
SCHEDULERS_PORT
: Port to listen to. Default:8080
SCHEDULERS_HOST
: Host to listen to. Default: machine's hostnameSCHEDULERS_API_KEY
: API key to authenticate API calls. Default:None
SCHEDULERS_CALLBACK_TIMEOUT
: Default timeout for callback request in seconds. Default:10
SCHEDULERS_CALLBACK_RETRY_INTERVAL
: Default interval between callback retries in seconds. Default:1, 5, 30
. This also sets number of retries. The above example will retry 3 times with interval of 1, then 5 and finally 30 seconds. Repeating schedule will be executed again after the last retry regardless of previous schedule execution status.