Skip to content

Commit b58dafc

Browse files
authored
Remove RQ dependency (#230)
1 parent e87f8e9 commit b58dafc

File tree

108 files changed

+6192
-2728
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+6192
-2728
lines changed

.github/actions/test-coverage/action.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ outputs:
1717
runs:
1818
using: "composite"
1919
steps:
20-
- name: Run Tests with coverage
20+
- name: Run regular tests with coverage
2121
shell: bash
2222
run: |
2323
cd testproject
24-
poetry run coverage run manage.py test scheduler
24+
poetry run coverage run manage.py test --exclude-tag multiprocess scheduler
2525
- name: Coverage report
2626
id: coverage_report
2727
shell: bash

.github/workflows/test.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ jobs:
2727
run: |
2828
poetry run ruff check
2929
30-
test:
30+
test-regular:
3131
needs: [ 'ruff' ]
3232
runs-on: ubuntu-latest
3333
name: "Run tests ${{ matrix.python-version }}/${{ matrix.django-version }}/${{ matrix.broker }}"
3434
strategy:
3535
max-parallel: 6
3636
matrix:
37-
python-version: [ '3.10', '3.11', '3.12', '3.13' ]
37+
python-version: [ '3.11', '3.12', '3.13' ]
3838
django-version: [ '5.0.7', '5.1.7' ]
3939
broker: [ 'redis', 'fakeredis', 'valkey' ]
4040
include:
@@ -110,7 +110,7 @@ jobs:
110110
else
111111
export BROKER_PORT=6379
112112
fi
113-
poetry run python manage.py test scheduler
113+
poetry run python manage.py test --exclude-tag multiprocess scheduler
114114
115115
# Steps for coverage check
116116
- name: Run tests with coverage
@@ -141,7 +141,7 @@ jobs:
141141
# write permission is required for auto-labeler
142142
# otherwise, read permission is required at least
143143
pull-requests: write
144-
needs: test
144+
needs: test-regular
145145
runs-on: ubuntu-latest
146146
steps:
147147
- uses: release-drafter/release-drafter@v6

SECURITY.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
## Supported Versions
44

5-
| Version | Supported |
6-
|-------------|--------------------|
7-
| 2023.latest | :white_check_mark: |
5+
| Version | Supported |
6+
|----------|--------------------|
7+
| 4.latest | :white_check_mark: |
88

99
## Reporting a Vulnerability
1010

docs/changelog.md

+36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,41 @@
11
# Changelog
22

3+
## v4.0.0b1 🌈
4+
5+
### Breaking Changes
6+
7+
This version is a full revamp of the package. The main changes are related to removing the RQ dependency.
8+
Worker/Queue/Job are all implemented in the package itself. This change allows for more flexibility and control over
9+
the tasks.
10+
11+
Management commands:
12+
13+
- `rqstats` => `scheduler_stats`
14+
- `rqworker` => `scheduler_worker`
15+
16+
Settings:
17+
18+
- `SCHEDULER_CONFIG` is now a `SchedulerConfiguration` object to help IDE guide settings.
19+
- `SCHEDULER_QUEUES` is now a list of `QueueConfiguration` objects to help IDE guide settings.
20+
- Configuring queue to use `SSL`/`SSL_CERT_REQS`/`SOCKET_TIMEOUT` is now done using `CONNECTION_KWARGS` in
21+
`QueueConfiguration`
22+
```python
23+
SCHEDULER_QUEUES: Dict[str, QueueConfiguration] = {
24+
'default': QueueConfiguration(
25+
HOST='localhost',
26+
PORT=6379,
27+
USERNAME='some-user',
28+
PASSWORD='some-password',
29+
CONNECTION_KWARGS={ # Eventual additional Broker connection arguments
30+
'ssl_cert_reqs': 'required',
31+
'ssl':True,
32+
},
33+
),
34+
# ...
35+
}
36+
```
37+
- For how to configure in `settings.py`, please see the [settings documentation](./configuration.md).
38+
339
## v3.0.1 🌈
440

541
### 🐛 Bug Fixes

docs/commands.md

+60-17
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,43 @@
11
# Management commands
22

3-
## rqworker
3+
## `scheduler_worker` - Create a worker
44

55
Create a new worker with a scheduler for specific queues by order of priority.
66
If no queues are specified, will run on default queue only.
77

88
All queues must have the same redis settings on `SCHEDULER_QUEUES`.
99

1010
```shell
11-
usage: manage.py rqworker [-h] [--pid PIDFILE] [--burst] [--name NAME] [--worker-ttl WORKER_TTL] [--max-jobs MAX_JOBS]
12-
[--fork-job-execution FORK_JOB_EXECUTION] [--job-class JOB_CLASS] [--sentry-dsn SENTRY_DSN] [--sentry-debug]
13-
[--sentry-ca-certs SENTRY_CA_CERTS] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH]
14-
[--traceback] [--no-color] [--force-color] [--skip-checks]
15-
[queues ...]
11+
usage: manage.py scheduler_worker [-h] [--pid PIDFILE] [--name NAME] [--worker-ttl WORKER_TTL] [--fork-job-execution FORK_JOB_EXECUTION] [--sentry-dsn SENTRY_DSN] [--sentry-debug] [--sentry-ca-certs SENTRY_CA_CERTS] [--burst]
12+
[--max-jobs MAX_JOBS] [--max-idle-time MAX_IDLE_TIME] [--with-scheduler] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color]
13+
[--skip-checks]
14+
[queues ...]
1615

1716
positional arguments:
1817
queues The queues to work on, separated by space, all queues should be using the same redis
1918

2019
options:
2120
-h, --help show this help message and exit
2221
--pid PIDFILE file to write the worker`s pid into
23-
--burst Run worker in burst mode
2422
--name NAME Name of the worker
2523
--worker-ttl WORKER_TTL
2624
Default worker timeout to be used
27-
--max-jobs MAX_JOBS Maximum number of jobs to execute before terminating worker
2825
--fork-job-execution FORK_JOB_EXECUTION
2926
Fork job execution to another process
30-
--job-class JOB_CLASS
31-
Jobs class to use
3227
--sentry-dsn SENTRY_DSN
3328
Sentry DSN to use
3429
--sentry-debug Enable Sentry debug mode
3530
--sentry-ca-certs SENTRY_CA_CERTS
3631
Path to CA certs file
32+
--burst Run worker in burst mode
33+
--max-jobs MAX_JOBS Maximum number of jobs to execute before terminating worker
34+
--max-idle-time MAX_IDLE_TIME
35+
Maximum number of seconds to wait for new job before terminating worker
36+
--with-scheduler Run worker with scheduler, default to True
3737
--version Show program's version number and exit.
3838
-v {0,1,2,3}, --verbosity {0,1,2,3}
3939
Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
40-
--settings SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the
41-
DJANGO_SETTINGS_MODULE environment variable will be used.
40+
--settings SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used.
4241
--pythonpath PYTHONPATH
4342
A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
4443
--traceback Raise on CommandError exceptions.
@@ -49,7 +48,7 @@ options:
4948
5049
5150
52-
## export
51+
## `export` - Export scheduled tasks
5352
5453
Export all scheduled tasks from django db to json/yaml format.
5554
@@ -62,7 +61,7 @@ Result should be (for json):
6261
```json
6362
[
6463
{
65-
"model": "ScheduledJob",
64+
"model": "CronTaskType",
6665
"name": "Scheduled Task 1",
6766
"callable": "scheduler.tests.test_job",
6867
"callable_args": [
@@ -83,7 +82,7 @@ Result should be (for json):
8382
]
8483
```
8584
86-
## import
85+
## `import` - Import scheduled tasks
8786
8887
A json/yaml that was exported using the `export` command
8988
can be imported to django.
@@ -96,18 +95,62 @@ can be imported to django.
9695
python manage.py import -f {yaml,json} --filename {SOURCE-FILE}
9796
```
9897
99-
## run_job
98+
## `run_job` - Run a job immediately
10099
101100
Run a method in a queue immediately.
102101
103102
```shell
104103
python manage.py run_job {callable} {callable args ...}
105104
```
106105
107-
## delete failed jobs
106+
## `delete_failed_jobs` - delete failed jobs
108107
109108
Run this to empty failed jobs registry from a queue.
110109
111110
```shell
112111
python manage.py delete_failed_jobs
113112
```
113+
114+
## `scheduler_stats` - Show scheduler stats
115+
116+
Prints scheduler stats as a table, json, or yaml, example:
117+
118+
```shell
119+
$ python manage.py scheduler_stats
120+
121+
Django-Scheduler CLI Dashboard
122+
123+
--------------------------------------------------------------------------------
124+
| Name | Queued | Active | Finished | Canceled | Workers |
125+
--------------------------------------------------------------------------------
126+
| default | 0 | 0 | 0 | 0 | 0 |
127+
| low | 0 | 0 | 0 | 0 | 0 |
128+
| high | 0 | 0 | 0 | 0 | 0 |
129+
| medium | 0 | 0 | 0 | 0 | 0 |
130+
| another | 0 | 0 | 0 | 0 | 0 |
131+
--------------------------------------------------------------------------------
132+
```
133+
134+
```shell
135+
usage: manage.py scheduler_stats [-h] [-j] [-y] [-i INTERVAL] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks]
136+
137+
Print statistics
138+
139+
options:
140+
-h, --help show this help message and exit
141+
-j, --json Output statistics as JSON
142+
-y, --yaml Output statistics as YAML
143+
-i INTERVAL, --interval INTERVAL
144+
Poll statistics every N seconds
145+
--version Show program's version number and exit.
146+
-v {0,1,2,3}, --verbosity {0,1,2,3}
147+
Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
148+
--settings SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used.
149+
--pythonpath PYTHONPATH
150+
A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
151+
--traceback Raise on CommandError exceptions.
152+
--no-color Don't colorize the command output.
153+
--force-color Force colorization of the command output.
154+
--skip-checks Skip system checks.
155+
156+
```

docs/configuration.md

+34-28
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,41 @@
55
All default settings for scheduler can be in one dictionary in `settings.py`:
66

77
```python
8-
SCHEDULER_CONFIG = {
9-
'EXECUTIONS_IN_PAGE': 20,
10-
'DEFAULT_RESULT_TTL': 500,
11-
'DEFAULT_TIMEOUT': 300, # 5 minutes
12-
'SCHEDULER_INTERVAL': 10, # 10 seconds
13-
'BROKER': 'redis',
14-
}
15-
SCHEDULER_QUEUES = {
16-
'default': {
17-
'HOST': 'localhost',
18-
'PORT': 6379,
19-
'DB': 0,
20-
'USERNAME': 'some-user',
21-
'PASSWORD': 'some-password',
22-
'DEFAULT_TIMEOUT': 360,
23-
'CLIENT_KWARGS': { # Eventual additional Redis connection arguments
24-
'ssl_cert_reqs': None,
8+
from typing import Dict
9+
10+
from scheduler.settings_types import SchedulerConfig, Broker, QueueConfiguration, UnixSignalDeathPenalty
11+
12+
13+
SCHEDULER_CONFIG = SchedulerConfig(
14+
EXECUTIONS_IN_PAGE=20,
15+
SCHEDULER_INTERVAL=10,
16+
BROKER=Broker.REDIS,
17+
CALLBACK_TIMEOUT=60, # Callback timeout in seconds (success/failure/stopped)
18+
# Default values, can be overriden per task/job
19+
DEFAULT_SUCCESS_TTL=10 * 60, # Time To Live (TTL) in seconds to keep successful job results
20+
DEFAULT_FAILURE_TTL=365 * 24 * 60 * 60, # Time To Live (TTL) in seconds to keep job failure information
21+
DEFAULT_JOB_TTL=10 * 60, # Time To Live (TTL) in seconds to keep job information
22+
DEFAULT_JOB_TIMEOUT=5 * 60, # timeout (seconds) for a job
23+
# General configuration values
24+
DEFAULT_WORKER_TTL=10 * 60, # Time To Live (TTL) in seconds to keep worker information after last heartbeat
25+
DEFAULT_MAINTENANCE_TASK_INTERVAL=10 * 60, # The interval to run maintenance tasks in seconds. 10 minutes.
26+
DEFAULT_JOB_MONITORING_INTERVAL=30, # The interval to monitor jobs in seconds.
27+
SCHEDULER_FALLBACK_PERIOD_SECS=120, # Period (secs) to wait before requiring to reacquire locks
28+
DEATH_PENALTY_CLASS=UnixSignalDeathPenalty,
29+
)
30+
SCHEDULER_QUEUES: Dict[str, QueueConfiguration] = {
31+
'default': QueueConfiguration(
32+
HOST='localhost',
33+
PORT=6379,
34+
USERNAME='some-user',
35+
PASSWORD='some-password',
36+
CONNECTION_KWARGS={ # Eventual additional Broker connection arguments
37+
'ssl_cert_reqs': 'required',
38+
'ssl': True,
2539
},
26-
'TOKEN_VALIDATION_METHOD': None, # Method to validate auth-header
27-
},
28-
'high': {
29-
'URL': os.getenv('REDISTOGO_URL', 'redis://localhost:6379/0'), # If you're on Heroku
30-
'DEFAULT_TIMEOUT': 500,
31-
},
32-
'low': {
33-
'HOST': 'localhost',
34-
'PORT': 6379,
35-
'DB': 0,
36-
}
40+
),
41+
'high': QueueConfiguration(URL=os.getenv('REDISTOGO_URL', 'redis://localhost:6379/0')),
42+
'low': QueueConfiguration(HOST='localhost', PORT=6379, DB=0, ASYNC=False),
3743
}
3844
```
3945

docs/drt-model.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Worker related flows
22

3-
Running `python manage.py startworker --name 'X' --queues high default low`
3+
Running `python manage.py scheduler_worker --name 'X' --queues high default low`
44

55
## Register new worker for queues
66
```mermaid
@@ -48,8 +48,8 @@ sequenceDiagram
4848
note over worker,job: Find next job
4949
5050
loop over queueKeys until job to run is found or all queues are empty
51-
worker ->>+ queue: get next job id and remove it or None (zrange+zpop)
52-
queue -->>- worker: job id / nothing
51+
worker ->>+ queue: get next job name and remove it or None (zrange+zpop)
52+
queue -->>- worker: job name / nothing
5353
end
5454
5555
note over worker,job: Execute job or sleep

0 commit comments

Comments
 (0)