|
1 | | -django_dbq |
| 1 | +django-db-queue |
2 | 2 | ========== |
| 3 | +[](https://magnum.travis-ci.com/dabapps/django-db-queue) |
3 | 4 |
|
4 | | -Simple databased-backed job queue |
| 5 | +Simple databased-backed job queue. Jobs are defined in your settings, and are processed by management commands. |
| 6 | + |
| 7 | + |
| 8 | +Asynchronous tasks are run via a *job queue*. This system is designed to support multi-step job workflows. |
| 9 | + |
| 10 | +### Terminology |
| 11 | + |
| 12 | +#### Job |
| 13 | + |
| 14 | +The top-level abstraction of a standalone piece of work. Jobs are stored in the database (ie they are represented as Django model instances). |
| 15 | + |
| 16 | +#### Task |
| 17 | + |
| 18 | +Jobs are processed to completion by *tasks*. These are simply Python functions, which must take a single argument - the `Job` instance being processed. A single job will often require processing by more than one task to be completed fully. Creating the task functions is the responsibility of the developer. For example: |
| 19 | + |
| 20 | + def my_task(job): |
| 21 | + logger.info("Doing some hard work") |
| 22 | + do_some_hard_work() |
| 23 | + |
| 24 | +#### Workspace |
| 25 | + |
| 26 | +The *workspace* is an area that tasks within a single job can use to communicate with each other. It is implemented as a Python dictionary, available on the `job` instance passed to tasks as `job.workspace`. The initial workspace of a job can be empty, or can contain some parameters that the tasks require (for example, API access tokens, account IDs etc). A single task can edit the workspace, and the modified workspace will be passed on to the next task in the sequence. For example: |
| 27 | + |
| 28 | + def my_first_task(job): |
| 29 | + job.workspace['message'] = 'Hello, task 2!' |
| 30 | + |
| 31 | + def my_second_task(job): |
| 32 | + logger.info("Task 1 says: %s" % job.workspace['message']) |
| 33 | + |
| 34 | +#### Worker process |
| 35 | + |
| 36 | +A *worker process* is a long-running process, implemented as a Django management command, which is responsible for executing the tasks associated with a job. There may be many worker processes running concurrently in the final system. Worker processes wait for a new job to be created in the database, and call the each associated task in the correct sequeunce.. A worker can be started using `python manage.py worker`, and a single worker instance is included in the development `procfile`. |
| 37 | + |
| 38 | +### Configuration |
| 39 | + |
| 40 | +Jobs are configured in the Django `settings.py` file. The `JOBS` setting is a dictionary mapping a *job name* (eg `import_hats`) to a *list* of one or more task function paths. For example: |
| 41 | + |
| 42 | + JOBS = { |
| 43 | + 'import_hats': ['apps.hat_hatter.import_hats.step_one', 'apps.hat_hatter.import_hats.step_two'], |
| 44 | + } |
| 45 | + |
| 46 | +### Job states |
| 47 | + |
| 48 | +Jobs have a `state` field which can have one of the following values: |
| 49 | + |
| 50 | +* `NEW` (has been created, waiting for a worker process to run the next task) |
| 51 | +* `READY` (has run a task before, awaiting a worker process to run the next task) |
| 52 | +* `PROCESSING` (a task is currently being processed by a worker) |
| 53 | +* `COMPLETED` (all job tasks have completed successfully) |
| 54 | +* `FAILED` (a job task failed) |
| 55 | + |
| 56 | +### API |
| 57 | + |
| 58 | +#### Management commands |
| 59 | + |
| 60 | +For debugging/development purposes, a simple management command is supplied to create jobs: |
| 61 | + |
| 62 | + manage.py create_job <job_name> --workspace '{"key": "value"}' |
| 63 | + |
| 64 | +The `workspace` flag is optional. If supplied, it must be a valid JSON string. |
| 65 | + |
| 66 | +To start a worker: |
| 67 | + |
| 68 | + manage.py worker |
0 commit comments