Skip to content

Commit

Permalink
Merge pull request #3 from kohkimakimoto/workerapp-example
Browse files Browse the repository at this point in the history
Workerapp example
  • Loading branch information
kohkimakimoto authored Dec 1, 2019
2 parents 2062251 + 2f51c9f commit 6127337
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 10 deletions.
38 changes: 31 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,36 @@ $ hq serve
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 lost 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](#configuration).
> Note: Running HQ server without any configuration like the above can cause to lost 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](#configuration).
You can push a job by using the following `curl` command:
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`](./examples/workerapp.py) script and add it executable permission and then run the script like the following:

```
$ curl -XPOST http://localhost:19900/job -H "Content-Type: application/json" -d '{"url": "http://localhost:8080/example", "payload": {"message": "Hello world!"}}'
$ ./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----
```

## Configuration
Expand Down Expand Up @@ -167,13 +191,13 @@ If the above example job is executed, HQ will send like the following HTTP reque
```http
POST /example HTTP/1.1
Host: your-worker-app-server
Content-Type: application/json
User-Agent: HQ/1.0.0
Content-Type: application/json
Content-Length: 26
X-Hq-Job-Id: 109192606348480512
Accept-Encoding: gzip
{
"message": "Hello world!"
}
{"message":"Hello world!"}
```

## HTTP API
Expand Down
2 changes: 1 addition & 1 deletion build/scripts/config
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export PRODUCT_NAME="hq"
export PRODUCT_VERSION="1.0.0"
export PRODUCT_VERSION="1.1.0"
export COMMIT_HASH=`git log --pretty=format:%H -n 1`
62 changes: 62 additions & 0 deletions examples/workerapp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env python
from __future__ import division, print_function, absolute_import, unicode_literals
try:
from http.server import HTTPServer, SimpleHTTPRequestHandler
except ImportError:
# fallback for python2
from SimpleHTTPServer import SimpleHTTPRequestHandler
from BaseHTTPServer import HTTPServer
import argparse
import sys

# RequestHandler
class RequestHandler(SimpleHTTPRequestHandler, object):
def do_GET(self):
# super(RequestHandler, self).do_GET()s
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b"It works!")

def do_POST(self):
rawPostData = ""
length = self.headers.get('Content-Length')
if (length):
rawPostData = self.rfile.read(int(length))
jobId = self.headers.get('X-Hq-Job-Id')
if not jobId:
jobId = "unknown"

print("--POST REQUEST BEGIN--")
print("%s %s\n%s" % (self.command, self.path, self.headers))
print("%s" % (rawPostData))
print("--POST REQUEST END----")

self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b"Got a job: " + jobId)

# main
def main():
parser = argparse.ArgumentParser(
description="An example worker web app for HQ",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
An example worker web app for HQ.
"""
)

parser.add_argument('-H', '--host', dest="host", default="")
parser.add_argument('-p', '--port', dest="port", type=int, default=8000)
args = parser.parse_args()

port = args.port
host = args.host

httpd = HTTPServer((host, port), RequestHandler)
print("Serving at port", port)
httpd.serve_forever()

if __name__ == '__main__': main()
8 changes: 7 additions & 1 deletion server/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"github.com/kohkimakimoto/hq/hq"
"github.com/pkg/errors"
"io"
"io/ioutil"
"net/http"
"sync/atomic"
Expand Down Expand Up @@ -138,11 +139,16 @@ func (d *Dispatcher) work(job *hq.Job) {
}

func (d *Dispatcher) runHttpWorker(job *hq.Job, ctx context.Context) error {
var reqBody io.Reader
if job.Payload != nil && !bytes.Equal(job.Payload, []byte("null")) {
reqBody = bytes.NewReader(job.Payload)
}

// worker
req, err := http.NewRequest(
"POST",
job.URL,
bytes.NewReader(job.Payload),
reqBody,
)
if err != nil {
return errors.Wrap(err, "failed to create new request")
Expand Down
2 changes: 1 addition & 1 deletion ui/src/screens/JobsNewScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const JobsNewScreen: React.FC = () => {

(async () => {
const postedJob = await api.createJob({
name: name,
name: job.name,
comment: job.comment,
url: job.url,
payload: job.payload,
Expand Down

0 comments on commit 6127337

Please sign in to comment.