HQ is a simplistic, language agnostic job queue engine communicated by HTTP messages.
HQ is implemented as a standalone JSON over HTTP API server. When you push a job to the HQ server, it stores the job in the internal queue database and sends asynchronous HTTP POST request to a URL that specified in the job.
Worker applications that actually run the jobs are web applications. So you can implement applications for the jobs in Any programming language that can talk HTTP (such as Go, PHP, Python, etc).
┌────────────────────────────────────────────────────────────────┐
┌───┐ │HQ server ┌──────┐│ ┌──────────┐
│app│──POST /job──>┼┐ ┌───────────────────┐ ┌>│worker│┼──POST /xxx──>│worker app│
└───┘ ││ │queue │ │ └──────┘│ └──────────┘
┌───┐ ││ │┌───┐ ┌───┐ ┌───┐│ ┌──────────┐│ ┌──────┐│ ┌──────────┐
│app│──POST /job──>┼┼─enqueue->││job│ │job│...│job││-dequeue->│dispatcher│┼>│worker│┼──POST /xxx──>│worker app│
└───┘ ││ │└───┘ └───┘ └───┘│ └──────────┘│ └──────┘│ └──────────┘
┌───┐ ││ │ │ │ ┌──────┐│ ┌──────────┐
│app│──POST /job──>┼┘ └───────────────────┘ └>│worker│┼──POST /xxx──>│worker app│
└───┘ │ └──────┘│ └──────────┘
└────────────────────────────────────────────────────────────────┘
HQ lives in a single binary without external dependencies. You can download a precompiled binary at the Github releases page.
You can also use RPM package that is stored in the same releases page. It is useful because it configures systemd service automatically.
It is very easy to get started on HQ. After installing HQ, run hq serve
in your terminal.
$ hq serve
2019-04-18T18:56:25+09:00 WARN Your 'data_dir' configuration is not set. HQ server uses a temporary directory that is deleted after the process terminates.
2019-04-18T18:56:25+09:00 WARN Created temporary data directory: /var/folders/7q/7yfsnkpj09n6s1pvlktkpp6h0000gn/T/hq_data_718224193
2019-04-18T18:56:25+09:00 INFO Opened data directory: /var/folders/7q/7yfsnkpj09n6s1pvlktkpp6h0000gn/T/hq_data_718224193
2019-04-18T18:56:25+09:00 INFO Opened boltdb: /var/folders/7q/7yfsnkpj09n6s1pvlktkpp6h0000gn/T/hq_data_718224193/server.bolt
2019-04-18T18:56:25+09:00 INFO The server Listening on 0.0.0.0:19900 (pid: 74090)
Note: Running HQ server without any configuration like the above can cause to lose queued jobs, because HQ uses temporary directory to store jobs. Therefore this should be used only on DEV environment. When you use HQ on your production environment, You should set a proper configuration file. See Configuration.
Next, you must launch your worker application. It is a web application that should be implemented for your purpose. But this time, you can use an example web app I made. Download workerapp.py
script and add it executable permission and then run the script like the following:
$ ./workerapp.py
Serving at port 8000
This is a web application that just outputs HTTP post request info to the console.
You are ready to push a job. You can push a job to HQ by using the following curl
command:
$ curl -XPOST http://localhost:19900/job -H "Content-Type: application/json" -d '{"url": "http://localhost:8000/", "payload": {"message": "Hello world!"}}'
workerapp.py
will get a job from HQ and output like the following message.
--POST REQUEST BEGIN--
POST /
Host: localhost:8000
User-Agent: HQ/1.0.0
Content-Length: 27
Content-Type: application/json
X-Hq-Job-Id: 121128807380811776
Accept-Encoding: gzip
{"message": "Hello world!"}
--POST REQUEST END----
The config file must be written in TOML. You can specify the config file by -c
or -config-file
option when HQ runs like the following.
$ hq serve -c /path/to/config.toml
server_id = 0
addr = "0.0.0.0:19900"
data_dir = "/var/lib/hq"
log_level = "info"
log_file = "/var/log/hq/hq.log"
access_log_file = "/var/log/hq/access.log"
queues = 8192
dispatchers = 1
max_workers = 0
shutdown_timeout = 10
job_lifetime = 2419200
job_list_default_limit = 0
ui = true
ui_basename = "/ui"
-
server_id
(number): This is used to generate Job ID. HQ uses go-katsubushi to allocate unique ID. If you want Job ID to be unique on mulitple servers, You need to setserver_id
unique on each servers. The default is0
. -
addr
(string): The listen address to the HQ server process. The default is0.0.0.0:19900
. -
data_dir
(string): The data directory to store all generated data by the HQ sever. You should set the parameter to keep jobs persistantly. If you doesn't set it, HQ uses a temporary directory that is deleted after the process terminates. -
log_level
(string): The log level (debug|info|warn|error
). The default isinfo
. -
log_file
(string): The log file path. If you do not set, HQ writes log to STDOUT. -
access_log_file
(string):The access log file path. If you do not set, HQ writes log to STDOUT. -
queues
(number): Size of queue. The default is8192
. -
dispatchers
(number): Number of dispatchers. The default isruntime.NumCPU()
. -
max_workers
(number): Number of max workers. The dispacher can execute multiple workers concurrently. This config is limit how many each dispatcher can run workers concurrently. For example, If you setdispatcher = 2
andmax_workers = 3
, HQ can run max6
workers at the same time. If you setmax_workers = 0
, each dispacher run only one worker synchronously. The default is0
. -
shutdown_timeout
(number): This is time how many seconds HQ waits executing jobs to finish in a shutdown process. If HQ server process receivesSIGINT
orSIGTERM
, it try to shutdown itself. If HQ has executing workers, it waits workers to finish or number of seconds of this config. The default is10
. -
job_lifetime
(number): HQ removes old finished jobs automatically. This config sets time how many seconds HQ keeps jobs. If you set it0
, HQ does not remove any jobs. The default is2419200
(28 days). -
job_list_default_limit
(number): The defaultlimit
value ofGET /job
. The default is0
(no limit). -
ui
(boolean): Enables built-in Web UI. The default istrue
. -
ui_basename
(string): The built-in Web UI URL. For example, if you set it/foo
, The Web UI will be provided on the url likehttp://localhost:19900/foo
. The default is/ui
.
Job in HQ is a JSON object as the following:
{
"canceled": false,
"comment": "This is an example job!",
"createdAt": "2019-10-29T07:32:26.054Z",
"err": "",
"failure": false,
"finishedAt": "2019-10-29T07:32:28.548Z",
"headers": null,
"id": "109192606348480512",
"name": "example-job",
"output": "OK",
"payload": {
"message": "Hello world!"
},
"running": false,
"startedAt": "2019-10-29T07:32:28.252Z",
"status": "success",
"statusCode": 200,
"success": true,
"timeout": 0,
"url": "http://your-worker-app-server/example",
"waiting": false
}
Jobs are managed internal database in HQ. To create and push a new job, You can use POST /job
API.
The pushed job is stored in the queue and executed by the HQ worker. The HQ worker constructs HTTP POST request from the job. You can customize this request headers and JSON payload by the job properties.
If the above example job is executed, HQ will send like the following HTTP request:
POST /example HTTP/1.1
Host: your-worker-app-server
User-Agent: HQ/1.0.0
Content-Type: application/json
Content-Length: 26
X-Hq-Job-Id: 109192606348480512
Accept-Encoding: gzip
{"message":"Hello world!"}
HQ core functions are provided via RESTful HTTP API.
Overview of endpoints:
GET /
: Gets HQ info.GET /stats
: Gets the HQ server statistics.POST /job
: Pushes a new job.GET /job
: Lists jobs.GET /job/{id}
: Gets a job.DELETE /job/{id}
: Deletes a job.POST /job/{id}/restart
: Restarts a job.POST /job/{id}/stop
: Stops a job.
By default, the output of all HTTP API requests is minimized JSON. If the client passes pretty
on the query string, formatted JSON will be returned.
Gets HQ info.
GET /
{
"version": "1.0.0",
"commitHash": "e78e5977ffecffce7f5118e002069dd05165deb6"
}
Gets the HQ server statistics.
GET /stats
{
"queues": 8192,
"dispatchers": 8,
"maxWorkers": 0,
"numWorkers": 0,
"numJobsInQueue": 0,
"numJobsWaiting": 0,
"numJobsRunning": 0,
"numStoredJobs": 67,
"numJobsInLastMinute": 0
}
Pushes a new job.
POST /job
{
"url": "https://your-worker-app-server/example",
"name": "example",
"comment": "This is an example job!",
"payload": {
"message": "Hello world!"
},
"headers": {
"X-Custom-Token": "xxxxxxx"
},
"timeout": 0
}
url
(string,required): The URL to send HTTP request to a worker application.name
(string): The name of this job. You can set it an arbitrary string. This property is used by searching of theGET /job
. If you do not set it. HQ sets itdefault
automatically.comment
(string): The arbitrary text to describe this job.payload
(json): The payload on the HTTP request to a worker application.headers
(json): Custom HTTP headers on the HTTP request to a worker application.timeout
(number): timeout seconds of this job. The default is0
(no timeout).
{
"canceled": false,
"comment": "This is an example job!",
"createdAt": "2019-10-29T23:57:08.713Z",
"err": "",
"failure": false,
"finishedAt": null,
"headers": null,
"id": "109440416981450752",
"name": "example",
"output": "",
"payload": {
"message": "Hello world!"
},
"running": false,
"startedAt": null,
"status": "unfinished",
"statusCode": null,
"success": false,
"timeout": 0,
"url": "https://your-worker-app-server/example",
"waiting": false
}
Lists jobs.
GET /job?name={name}&begin={id}&reverse={true|false}&status={status}&limit={limit}
name
: Specifies a regular expression string to filter the jobs with job's nameterm
: Specifies a regular expression string to filter the jobs with job's id name, comment, url or statusbegin
: Load the jobs from ID. (default: 0)reverse
: Sort by descending ID.status
: Specifies STATUS to filter the jobs with job's status (running|waiting|canceling|failure|success|canceled|unfinished|unknown
).limit
: Max number of displaying jobs.
{
"jobs": [
{
"canceled": false,
"comment": "",
"createdAt": "2019-10-29T23:57:08.713Z",
"err": "failed to do http request: Post https://localhost/: dial tcp [::1]:443: connect: connection refused",
"failure": true,
"finishedAt": "2019-10-29T23:57:08.761Z",
"headers": null,
"id": "109440416981450752",
"name": "default",
"output": "",
"payload": {
"message": "Hello world!"
},
"running": false,
"startedAt": "2019-10-29T23:57:08.736Z",
"status": "failure",
"statusCode": null,
"success": false,
"timeout": 0,
"url": "https://localhost/",
"waiting": false
},
// ...
],
"hasNext": true,
"next": "109592774310887424",
"count": 1
}
Gets a job.
GET /job/{id}
id
: Job ID to get.
{
"canceled": false,
"comment": "",
"createdAt": "2019-10-29T23:57:08.713Z",
"err": "failed to do http request: Post https://localhost/: dial tcp [::1]:443: connect: connection refused",
"failure": true,
"finishedAt": "2019-10-29T23:57:08.761Z",
"headers": null,
"id": "109440416981450752",
"name": "default",
"output": "",
"payload": {
"message": "Hello world!"
},
"running": false,
"startedAt": "2019-10-29T23:57:08.736Z",
"status": "failure",
"statusCode": null,
"success": false,
"timeout": 0,
"url": "https://localhost/",
"waiting": false
}
Deletes a job.
DELETE /job/{id}
id
: Job ID to delete.
{
"id": "109440416981450752"
}
Restarts a job.
POST /job/{id}/restart
{
"copy": false
}
id
: Job ID to restart.copy
: If it settrue
, Restarts the copied job instead of updating the existed job.
{
"canceled": false,
"comment": "",
"createdAt": "2019-10-30T10:02:33.531Z",
"err": "",
"failure": false,
"finishedAt": null,
"headers": null,
"id": "109592774310887424",
"name": "default",
"output": "",
"payload": {
"message": "Hello world!"
},
"running": false,
"startedAt": null,
"status": "unfinished",
"statusCode": null,
"success": false,
"timeout": 0,
"url": "https://localhost/",
"waiting": false
}
Stops a job.
POST /job/{id}/stop
id
: Job ID to stop.
{
"id": "109440416981450752"
}
HQ also provides command-line interface to communicate HQ server. To view a list of the available commands, just run hq
without any arguments:
NAME:
hq - Simplistic job queue engine
USAGE:
hq [global options] command [command options] [arguments...]
VERSION:
2.0.0 (5bdbdaf31772c1f5cdd8feb2056e4d5fcafa7a51)
COMMANDS:
delete Deletes a job
info Displays a job detail
list Lists jobs
push Pushes a new job.
restart Restarts a job
serve Starts the HQ server process
stats Displays the HQ server statistics.
stop Stops a job
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--help, -h show help (default: false)
--version, -v print the version (default: false)
COPYRIGHT:
Copyright (c) 2019 Kohki Makimoto
See more detail, Run a sub command with -h
option.
HQ includes built-in Web UI. The web ui is enabled at default. See http://localhost:19900/ui
with your browser.
Kohki Makimoto kohki.makimoto@gmail.com
The MIT License (MIT)