django-tasks-redis 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_tasks_redis-0.1.0/LICENSE +21 -0
- django_tasks_redis-0.1.0/PKG-INFO +276 -0
- django_tasks_redis-0.1.0/README.md +242 -0
- django_tasks_redis-0.1.0/django_tasks_redis/__init__.py +8 -0
- django_tasks_redis-0.1.0/django_tasks_redis/admin.py +376 -0
- django_tasks_redis-0.1.0/django_tasks_redis/apps.py +8 -0
- django_tasks_redis-0.1.0/django_tasks_redis/backends.py +542 -0
- django_tasks_redis-0.1.0/django_tasks_redis/executor.py +629 -0
- django_tasks_redis-0.1.0/django_tasks_redis/management/__init__.py +0 -0
- django_tasks_redis-0.1.0/django_tasks_redis/management/commands/__init__.py +0 -0
- django_tasks_redis-0.1.0/django_tasks_redis/management/commands/purge_completed_redis_tasks.py +114 -0
- django_tasks_redis-0.1.0/django_tasks_redis/management/commands/run_redis_tasks.py +134 -0
- django_tasks_redis-0.1.0/django_tasks_redis/urls.py +28 -0
- django_tasks_redis-0.1.0/django_tasks_redis/utils.py +196 -0
- django_tasks_redis-0.1.0/django_tasks_redis/views.py +120 -0
- django_tasks_redis-0.1.0/django_tasks_redis.egg-info/PKG-INFO +276 -0
- django_tasks_redis-0.1.0/django_tasks_redis.egg-info/SOURCES.txt +26 -0
- django_tasks_redis-0.1.0/django_tasks_redis.egg-info/dependency_links.txt +1 -0
- django_tasks_redis-0.1.0/django_tasks_redis.egg-info/requires.txt +7 -0
- django_tasks_redis-0.1.0/django_tasks_redis.egg-info/top_level.txt +1 -0
- django_tasks_redis-0.1.0/pyproject.toml +89 -0
- django_tasks_redis-0.1.0/setup.cfg +4 -0
- django_tasks_redis-0.1.0/tests/test_admin.py +291 -0
- django_tasks_redis-0.1.0/tests/test_backend.py +167 -0
- django_tasks_redis-0.1.0/tests/test_commands.py +127 -0
- django_tasks_redis-0.1.0/tests/test_executor.py +225 -0
- django_tasks_redis-0.1.0/tests/test_utils.py +146 -0
- django_tasks_redis-0.1.0/tests/test_views.py +181 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Shinya Okano
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-tasks-redis
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Redis/Valkey-backed task queue backend for Django 6.0's built-in task framework
|
|
5
|
+
Author-email: Shinya Okano <tokibito@gmail.com>
|
|
6
|
+
Maintainer-email: Shinya Okano <tokibito@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/tokibito/django-tasks-redis
|
|
9
|
+
Project-URL: Repository, https://github.com/tokibito/django-tasks-redis
|
|
10
|
+
Project-URL: Issues, https://github.com/tokibito/django-tasks-redis/issues
|
|
11
|
+
Keywords: django,tasks,redis,valkey,async,queue,background
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Web Environment
|
|
14
|
+
Classifier: Framework :: Django
|
|
15
|
+
Classifier: Framework :: Django :: 6.0
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Requires-Python: >=3.12
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: Django>=6.0
|
|
28
|
+
Requires-Dist: redis>=5.0.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-django>=4.5; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.8; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# django-tasks-redis
|
|
36
|
+
|
|
37
|
+
[](https://github.com/tokibito/django-tasks-redis/actions/workflows/ci.yml)
|
|
38
|
+
[](https://badge.fury.io/py/django-tasks-redis)
|
|
39
|
+
[](https://pypi.org/project/django-tasks-redis/)
|
|
40
|
+
[](https://opensource.org/licenses/MIT)
|
|
41
|
+
|
|
42
|
+
A Redis/Valkey-backed task queue backend for Django 6.0's built-in task framework.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- Full integration with Django 6.0's task framework (`django.tasks`)
|
|
47
|
+
- Redis Streams for reliable task queuing with consumer groups
|
|
48
|
+
- Support for both Redis and Valkey backends
|
|
49
|
+
- Delayed task execution with scheduled times
|
|
50
|
+
- Priority-based task processing
|
|
51
|
+
- Crash recovery with automatic task reclaim
|
|
52
|
+
- Django Admin integration for task monitoring and management
|
|
53
|
+
- HTTP endpoints for external triggers (webhooks, Cloud Scheduler, etc.)
|
|
54
|
+
|
|
55
|
+
## Architecture
|
|
56
|
+
|
|
57
|
+
```mermaid
|
|
58
|
+
sequenceDiagram
|
|
59
|
+
participant App as Application
|
|
60
|
+
participant Backend as RedisTaskBackend
|
|
61
|
+
participant Redis as Redis/Valkey
|
|
62
|
+
participant Worker as Worker Process
|
|
63
|
+
|
|
64
|
+
Note over App,Worker: Task Enqueue
|
|
65
|
+
App->>Backend: task.enqueue(args, kwargs)
|
|
66
|
+
Backend->>Backend: Validate & serialize args
|
|
67
|
+
Backend->>Redis: HSET task data (status=READY)
|
|
68
|
+
Backend->>Redis: XADD to priority stream
|
|
69
|
+
Redis-->>Backend: Message ID
|
|
70
|
+
Backend-->>App: TaskResult (id, status=READY)
|
|
71
|
+
|
|
72
|
+
Note over App,Worker: Task Execution
|
|
73
|
+
Worker->>Redis: XREADGROUP (consumer group)<br/>(blocks waiting for messages)
|
|
74
|
+
Redis-->>Worker: Message with task_id
|
|
75
|
+
Worker->>Redis: HGET task data
|
|
76
|
+
Redis-->>Worker: Task data
|
|
77
|
+
Worker->>Redis: HSET status=RUNNING
|
|
78
|
+
Worker->>Worker: Execute task function
|
|
79
|
+
alt Success
|
|
80
|
+
Worker->>Redis: HSET status=SUCCESSFUL,<br/>return_value, finished_at
|
|
81
|
+
else Failure
|
|
82
|
+
Worker->>Redis: HSET status=FAILED,<br/>errors, finished_at
|
|
83
|
+
end
|
|
84
|
+
Worker->>Redis: XACK (acknowledge message)
|
|
85
|
+
|
|
86
|
+
Note over App,Worker: Crash Recovery
|
|
87
|
+
Worker->>Redis: XAUTOCLAIM stale messages<br/>(claim_timeout exceeded)
|
|
88
|
+
Redis-->>Worker: Reclaimed messages
|
|
89
|
+
Worker->>Worker: Re-execute tasks
|
|
90
|
+
|
|
91
|
+
Note over App,Worker: Result Retrieval (Optional)
|
|
92
|
+
App->>Backend: backend.get_result(task_id)
|
|
93
|
+
Backend->>Redis: HGETALL task data
|
|
94
|
+
Redis-->>Backend: Task data
|
|
95
|
+
Backend-->>App: TaskResult (status, return_value, errors)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Requirements
|
|
99
|
+
|
|
100
|
+
- Python 3.12+
|
|
101
|
+
- Django 6.0+
|
|
102
|
+
- Redis 5.0+ or Valkey 7.2+
|
|
103
|
+
|
|
104
|
+
## Installation
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pip install django-tasks-redis
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Quick Start
|
|
111
|
+
|
|
112
|
+
1. Add `django_tasks_redis` to your `INSTALLED_APPS`:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
INSTALLED_APPS = [
|
|
116
|
+
# ...
|
|
117
|
+
"django_tasks_redis",
|
|
118
|
+
]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
2. Configure the task backend in your Django settings:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
TASKS = {
|
|
125
|
+
"default": {
|
|
126
|
+
"BACKEND": "django_tasks_redis.RedisTaskBackend",
|
|
127
|
+
"QUEUES": [], # Empty list = allow all queue names
|
|
128
|
+
"OPTIONS": {
|
|
129
|
+
"REDIS_URL": "redis://localhost:6379/0",
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
> **Note**: `QUEUES` controls which queue names are allowed. If omitted, only `"default"` queue is allowed. Set `QUEUES: []` (empty list) to allow all queue names, or specify explicit names like `["default", "emails"]`.
|
|
136
|
+
|
|
137
|
+
3. Define a task:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from django.tasks import task
|
|
141
|
+
|
|
142
|
+
@task
|
|
143
|
+
def send_email(to: str, subject: str, body: str):
|
|
144
|
+
# Send email logic here
|
|
145
|
+
pass
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
4. Enqueue the task:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
result = send_email.enqueue("user@example.com", "Hello", "World")
|
|
152
|
+
print(f"Task ID: {result.id}")
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
5. Run the worker:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
python manage.py run_redis_tasks
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Configuration Options
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
TASKS = {
|
|
165
|
+
"default": {
|
|
166
|
+
"BACKEND": "django_tasks_redis.RedisTaskBackend",
|
|
167
|
+
"QUEUES": [], # Empty list = allow all queue names
|
|
168
|
+
"OPTIONS": {
|
|
169
|
+
# Connection settings (use URL or individual settings)
|
|
170
|
+
"REDIS_URL": "redis://localhost:6379/0",
|
|
171
|
+
# Or use individual settings:
|
|
172
|
+
# "REDIS_HOST": "localhost",
|
|
173
|
+
# "REDIS_PORT": 6379,
|
|
174
|
+
# "REDIS_DB": 0,
|
|
175
|
+
# "REDIS_PASSWORD": None,
|
|
176
|
+
# "REDIS_SSL": False,
|
|
177
|
+
|
|
178
|
+
# Behavior settings
|
|
179
|
+
"REDIS_RESULT_TTL": 604800, # Result retention period (seconds), default 7 days
|
|
180
|
+
"REDIS_KEY_PREFIX": "django_tasks", # Redis key prefix
|
|
181
|
+
"REDIS_CONSUMER_GROUP": "django_tasks_workers", # Consumer group name
|
|
182
|
+
"REDIS_CLAIM_TIMEOUT": 300, # Stale message claim timeout (seconds)
|
|
183
|
+
"REDIS_BLOCK_TIMEOUT": 5000, # XREADGROUP block timeout (milliseconds)
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Management Commands
|
|
190
|
+
|
|
191
|
+
### run_redis_tasks
|
|
192
|
+
|
|
193
|
+
Start a worker to process tasks:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
python manage.py run_redis_tasks [options]
|
|
197
|
+
|
|
198
|
+
Options:
|
|
199
|
+
--queue QUEUE_NAME Process only tasks from specific queue
|
|
200
|
+
--backend BACKEND_NAME Backend name (default: default)
|
|
201
|
+
--continuous Continuous mode (don't exit)
|
|
202
|
+
--interval SECONDS Polling interval (default: 1)
|
|
203
|
+
--max-tasks N Maximum tasks to process (0=unlimited)
|
|
204
|
+
--workers N Number of worker threads (default: 1)
|
|
205
|
+
--claim-interval SECS Stale task claim interval (default: 60)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### purge_completed_redis_tasks
|
|
209
|
+
|
|
210
|
+
Delete completed tasks:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
python manage.py purge_completed_redis_tasks [options]
|
|
214
|
+
|
|
215
|
+
Options:
|
|
216
|
+
--days N Delete tasks completed N+ days ago
|
|
217
|
+
--status STATUS Target status (default: SUCCESSFUL,FAILED)
|
|
218
|
+
--batch-size N Batch delete size (default: 1000)
|
|
219
|
+
--dry-run Only show count, don't delete
|
|
220
|
+
--backend BACKEND_NAME Backend name (default: default)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Django Admin
|
|
224
|
+
|
|
225
|
+
The package provides Django Admin integration for viewing and managing tasks:
|
|
226
|
+
|
|
227
|
+
- View task list with status, priority, queue
|
|
228
|
+
- Filter by status, queue, backend
|
|
229
|
+
- Run selected tasks
|
|
230
|
+
- Retry failed tasks
|
|
231
|
+
|
|
232
|
+
## HTTP Endpoints
|
|
233
|
+
|
|
234
|
+
Include the URLs in your project:
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from django.urls import include, path
|
|
238
|
+
|
|
239
|
+
urlpatterns = [
|
|
240
|
+
# ...
|
|
241
|
+
path("tasks/", include("django_tasks_redis.urls")),
|
|
242
|
+
]
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Available endpoints:
|
|
246
|
+
|
|
247
|
+
- `POST /tasks/run/` - Process multiple tasks
|
|
248
|
+
- `POST /tasks/run-one/` - Process a single task
|
|
249
|
+
- `POST /tasks/execute/<task_id>/` - Execute specific task by ID
|
|
250
|
+
- `GET /tasks/status/<task_id>/` - Get task status
|
|
251
|
+
- `POST /tasks/purge/` - Purge completed tasks
|
|
252
|
+
|
|
253
|
+
## Public API
|
|
254
|
+
|
|
255
|
+
The `executor` module provides functions for programmatic task management:
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
from django_tasks_redis import executor
|
|
259
|
+
|
|
260
|
+
# Process tasks
|
|
261
|
+
result = executor.process_one_task(queue_name="default")
|
|
262
|
+
results = executor.process_tasks(max_tasks=10)
|
|
263
|
+
|
|
264
|
+
# Execute specific task
|
|
265
|
+
result = executor.run_task_by_id(task_id, allow_retry=True)
|
|
266
|
+
|
|
267
|
+
# Get pending task count
|
|
268
|
+
count = executor.get_pending_task_count()
|
|
269
|
+
|
|
270
|
+
# Purge completed tasks
|
|
271
|
+
deleted = executor.purge_completed_tasks(days=7)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
MIT License
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# django-tasks-redis
|
|
2
|
+
|
|
3
|
+
[](https://github.com/tokibito/django-tasks-redis/actions/workflows/ci.yml)
|
|
4
|
+
[](https://badge.fury.io/py/django-tasks-redis)
|
|
5
|
+
[](https://pypi.org/project/django-tasks-redis/)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
A Redis/Valkey-backed task queue backend for Django 6.0's built-in task framework.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Full integration with Django 6.0's task framework (`django.tasks`)
|
|
13
|
+
- Redis Streams for reliable task queuing with consumer groups
|
|
14
|
+
- Support for both Redis and Valkey backends
|
|
15
|
+
- Delayed task execution with scheduled times
|
|
16
|
+
- Priority-based task processing
|
|
17
|
+
- Crash recovery with automatic task reclaim
|
|
18
|
+
- Django Admin integration for task monitoring and management
|
|
19
|
+
- HTTP endpoints for external triggers (webhooks, Cloud Scheduler, etc.)
|
|
20
|
+
|
|
21
|
+
## Architecture
|
|
22
|
+
|
|
23
|
+
```mermaid
|
|
24
|
+
sequenceDiagram
|
|
25
|
+
participant App as Application
|
|
26
|
+
participant Backend as RedisTaskBackend
|
|
27
|
+
participant Redis as Redis/Valkey
|
|
28
|
+
participant Worker as Worker Process
|
|
29
|
+
|
|
30
|
+
Note over App,Worker: Task Enqueue
|
|
31
|
+
App->>Backend: task.enqueue(args, kwargs)
|
|
32
|
+
Backend->>Backend: Validate & serialize args
|
|
33
|
+
Backend->>Redis: HSET task data (status=READY)
|
|
34
|
+
Backend->>Redis: XADD to priority stream
|
|
35
|
+
Redis-->>Backend: Message ID
|
|
36
|
+
Backend-->>App: TaskResult (id, status=READY)
|
|
37
|
+
|
|
38
|
+
Note over App,Worker: Task Execution
|
|
39
|
+
Worker->>Redis: XREADGROUP (consumer group)<br/>(blocks waiting for messages)
|
|
40
|
+
Redis-->>Worker: Message with task_id
|
|
41
|
+
Worker->>Redis: HGET task data
|
|
42
|
+
Redis-->>Worker: Task data
|
|
43
|
+
Worker->>Redis: HSET status=RUNNING
|
|
44
|
+
Worker->>Worker: Execute task function
|
|
45
|
+
alt Success
|
|
46
|
+
Worker->>Redis: HSET status=SUCCESSFUL,<br/>return_value, finished_at
|
|
47
|
+
else Failure
|
|
48
|
+
Worker->>Redis: HSET status=FAILED,<br/>errors, finished_at
|
|
49
|
+
end
|
|
50
|
+
Worker->>Redis: XACK (acknowledge message)
|
|
51
|
+
|
|
52
|
+
Note over App,Worker: Crash Recovery
|
|
53
|
+
Worker->>Redis: XAUTOCLAIM stale messages<br/>(claim_timeout exceeded)
|
|
54
|
+
Redis-->>Worker: Reclaimed messages
|
|
55
|
+
Worker->>Worker: Re-execute tasks
|
|
56
|
+
|
|
57
|
+
Note over App,Worker: Result Retrieval (Optional)
|
|
58
|
+
App->>Backend: backend.get_result(task_id)
|
|
59
|
+
Backend->>Redis: HGETALL task data
|
|
60
|
+
Redis-->>Backend: Task data
|
|
61
|
+
Backend-->>App: TaskResult (status, return_value, errors)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Requirements
|
|
65
|
+
|
|
66
|
+
- Python 3.12+
|
|
67
|
+
- Django 6.0+
|
|
68
|
+
- Redis 5.0+ or Valkey 7.2+
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install django-tasks-redis
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Quick Start
|
|
77
|
+
|
|
78
|
+
1. Add `django_tasks_redis` to your `INSTALLED_APPS`:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
INSTALLED_APPS = [
|
|
82
|
+
# ...
|
|
83
|
+
"django_tasks_redis",
|
|
84
|
+
]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
2. Configure the task backend in your Django settings:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
TASKS = {
|
|
91
|
+
"default": {
|
|
92
|
+
"BACKEND": "django_tasks_redis.RedisTaskBackend",
|
|
93
|
+
"QUEUES": [], # Empty list = allow all queue names
|
|
94
|
+
"OPTIONS": {
|
|
95
|
+
"REDIS_URL": "redis://localhost:6379/0",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
> **Note**: `QUEUES` controls which queue names are allowed. If omitted, only `"default"` queue is allowed. Set `QUEUES: []` (empty list) to allow all queue names, or specify explicit names like `["default", "emails"]`.
|
|
102
|
+
|
|
103
|
+
3. Define a task:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from django.tasks import task
|
|
107
|
+
|
|
108
|
+
@task
|
|
109
|
+
def send_email(to: str, subject: str, body: str):
|
|
110
|
+
# Send email logic here
|
|
111
|
+
pass
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
4. Enqueue the task:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
result = send_email.enqueue("user@example.com", "Hello", "World")
|
|
118
|
+
print(f"Task ID: {result.id}")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
5. Run the worker:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
python manage.py run_redis_tasks
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Configuration Options
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
TASKS = {
|
|
131
|
+
"default": {
|
|
132
|
+
"BACKEND": "django_tasks_redis.RedisTaskBackend",
|
|
133
|
+
"QUEUES": [], # Empty list = allow all queue names
|
|
134
|
+
"OPTIONS": {
|
|
135
|
+
# Connection settings (use URL or individual settings)
|
|
136
|
+
"REDIS_URL": "redis://localhost:6379/0",
|
|
137
|
+
# Or use individual settings:
|
|
138
|
+
# "REDIS_HOST": "localhost",
|
|
139
|
+
# "REDIS_PORT": 6379,
|
|
140
|
+
# "REDIS_DB": 0,
|
|
141
|
+
# "REDIS_PASSWORD": None,
|
|
142
|
+
# "REDIS_SSL": False,
|
|
143
|
+
|
|
144
|
+
# Behavior settings
|
|
145
|
+
"REDIS_RESULT_TTL": 604800, # Result retention period (seconds), default 7 days
|
|
146
|
+
"REDIS_KEY_PREFIX": "django_tasks", # Redis key prefix
|
|
147
|
+
"REDIS_CONSUMER_GROUP": "django_tasks_workers", # Consumer group name
|
|
148
|
+
"REDIS_CLAIM_TIMEOUT": 300, # Stale message claim timeout (seconds)
|
|
149
|
+
"REDIS_BLOCK_TIMEOUT": 5000, # XREADGROUP block timeout (milliseconds)
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Management Commands
|
|
156
|
+
|
|
157
|
+
### run_redis_tasks
|
|
158
|
+
|
|
159
|
+
Start a worker to process tasks:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
python manage.py run_redis_tasks [options]
|
|
163
|
+
|
|
164
|
+
Options:
|
|
165
|
+
--queue QUEUE_NAME Process only tasks from specific queue
|
|
166
|
+
--backend BACKEND_NAME Backend name (default: default)
|
|
167
|
+
--continuous Continuous mode (don't exit)
|
|
168
|
+
--interval SECONDS Polling interval (default: 1)
|
|
169
|
+
--max-tasks N Maximum tasks to process (0=unlimited)
|
|
170
|
+
--workers N Number of worker threads (default: 1)
|
|
171
|
+
--claim-interval SECS Stale task claim interval (default: 60)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### purge_completed_redis_tasks
|
|
175
|
+
|
|
176
|
+
Delete completed tasks:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
python manage.py purge_completed_redis_tasks [options]
|
|
180
|
+
|
|
181
|
+
Options:
|
|
182
|
+
--days N Delete tasks completed N+ days ago
|
|
183
|
+
--status STATUS Target status (default: SUCCESSFUL,FAILED)
|
|
184
|
+
--batch-size N Batch delete size (default: 1000)
|
|
185
|
+
--dry-run Only show count, don't delete
|
|
186
|
+
--backend BACKEND_NAME Backend name (default: default)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Django Admin
|
|
190
|
+
|
|
191
|
+
The package provides Django Admin integration for viewing and managing tasks:
|
|
192
|
+
|
|
193
|
+
- View task list with status, priority, queue
|
|
194
|
+
- Filter by status, queue, backend
|
|
195
|
+
- Run selected tasks
|
|
196
|
+
- Retry failed tasks
|
|
197
|
+
|
|
198
|
+
## HTTP Endpoints
|
|
199
|
+
|
|
200
|
+
Include the URLs in your project:
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
from django.urls import include, path
|
|
204
|
+
|
|
205
|
+
urlpatterns = [
|
|
206
|
+
# ...
|
|
207
|
+
path("tasks/", include("django_tasks_redis.urls")),
|
|
208
|
+
]
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Available endpoints:
|
|
212
|
+
|
|
213
|
+
- `POST /tasks/run/` - Process multiple tasks
|
|
214
|
+
- `POST /tasks/run-one/` - Process a single task
|
|
215
|
+
- `POST /tasks/execute/<task_id>/` - Execute specific task by ID
|
|
216
|
+
- `GET /tasks/status/<task_id>/` - Get task status
|
|
217
|
+
- `POST /tasks/purge/` - Purge completed tasks
|
|
218
|
+
|
|
219
|
+
## Public API
|
|
220
|
+
|
|
221
|
+
The `executor` module provides functions for programmatic task management:
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
from django_tasks_redis import executor
|
|
225
|
+
|
|
226
|
+
# Process tasks
|
|
227
|
+
result = executor.process_one_task(queue_name="default")
|
|
228
|
+
results = executor.process_tasks(max_tasks=10)
|
|
229
|
+
|
|
230
|
+
# Execute specific task
|
|
231
|
+
result = executor.run_task_by_id(task_id, allow_retry=True)
|
|
232
|
+
|
|
233
|
+
# Get pending task count
|
|
234
|
+
count = executor.get_pending_task_count()
|
|
235
|
+
|
|
236
|
+
# Purge completed tasks
|
|
237
|
+
deleted = executor.purge_completed_tasks(days=7)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## License
|
|
241
|
+
|
|
242
|
+
MIT License
|