redqueue 0.11.2__tar.gz → 0.13.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.
- {redqueue-0.11.2 → redqueue-0.13.0}/CHANGELOG.md +69 -13
- {redqueue-0.11.2 → redqueue-0.13.0}/PKG-INFO +73 -4
- {redqueue-0.11.2 → redqueue-0.13.0}/README-zh-CN.md +85 -16
- {redqueue-0.11.2 → redqueue-0.13.0}/README.md +85 -16
- {redqueue-0.11.2 → redqueue-0.13.0}/docs/API.md +75 -15
- {redqueue-0.11.2 → redqueue-0.13.0}/pyproject.toml +4 -1
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/__init__.py +4 -3
- redqueue-0.13.0/src/redqueue/__main__.py +9 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/_version.py +1 -1
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/async_client.py +131 -118
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/backends/async_delay.py +7 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/backends/async_list.py +454 -430
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/backends/async_stream.py +5 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/backends/base.py +3 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/backends/delay.py +7 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/backends/list.py +451 -427
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/backends/stream.py +10 -1
- redqueue-0.13.0/src/redqueue/cli.py +538 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/client.py +85 -72
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/message.py +47 -1
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/monitoring.py +4 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/fakes.py +4 -1
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/test_availability.py +2 -0
- redqueue-0.13.0/tests/test_cli.py +356 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/test_project_skeleton.py +245 -137
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/test_real_redis_availability.py +1 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/.github/workflows/ci.yml +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/.gitignore +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/CODE_OF_CONDUCT.md +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/CONTRIBUTING.md +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/LICENSE +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/NOTICE +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/docs/RELEASE.md +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/README.md +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/__init__.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/async_list_queue.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/common.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/compatibility_check.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/custom_serializer.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/delayed_tasks.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/monitoring_hooks.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/stream_queue.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/examples/sync_list_queue.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/requirements.txt +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/scripts/check.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/backends/__init__.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/compat.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/config.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/connection.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/exceptions.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/src/redqueue/serialization.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/README.md +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/__init__.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/test_backend_contracts.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/test_integration_redis.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/test_performance.py +0 -0
- {redqueue-0.11.2 → redqueue-0.13.0}/tests/test_real_redis_performance.py +0 -0
|
@@ -7,24 +7,80 @@ All notable public release changes are documented here.
|
|
|
7
7
|
Development versions are tracked separately from formal release versions.
|
|
8
8
|
开发版本与正式版本分开管理。
|
|
9
9
|
|
|
10
|
-
## [0.
|
|
10
|
+
## [0.13.0] - 2026-06-27
|
|
11
11
|
|
|
12
|
-
###
|
|
12
|
+
### Added
|
|
13
13
|
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
- Added first-class `trace_id` support to `Message`, sync and async
|
|
15
|
+
`publish()`, sync and async `delay()`, List, Streams, and delayed task
|
|
16
|
+
backends.
|
|
17
|
+
- Added trace propagation through message envelopes, retry, dead-letter,
|
|
18
|
+
delayed release, and requeue flows while remaining compatible with existing
|
|
19
|
+
`headers["trace_id"]` messages.
|
|
20
|
+
- Added `trace_id` to monitoring events and CLI message output for lifecycle
|
|
21
|
+
correlation.
|
|
22
|
+
- Added CLI `--trace-id` support for `publish` and `delay`.
|
|
23
|
+
- Added `new_trace_id()` helper for callers that want RedQueue-generated trace
|
|
24
|
+
identifiers.
|
|
19
25
|
|
|
20
|
-
###
|
|
26
|
+
### 新增
|
|
21
27
|
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
28
|
+
- `Message`、同步和异步 `publish()`、同步和异步 `delay()`、List、Streams
|
|
29
|
+
和延迟任务后端新增一等 `trace_id` 支持。
|
|
30
|
+
- trace 会穿过消息 envelope、重试、死信、延迟释放和重放流程,并兼容已有的
|
|
31
|
+
`headers["trace_id"]` 消息。
|
|
32
|
+
- 监控事件和 CLI 消息输出新增 `trace_id`,方便按链路聚合生命周期事件。
|
|
33
|
+
- CLI 的 `publish` 和 `delay` 命令新增 `--trace-id`。
|
|
34
|
+
- 新增 `new_trace_id()` helper,方便调用方生成 RedQueue trace 标识。
|
|
26
35
|
|
|
27
|
-
## [0.
|
|
36
|
+
## [0.12.0] - 2026-06-23
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- Added the `redqueue` CLI and `python -m redqueue` module entry point for
|
|
41
|
+
developer debugging.
|
|
42
|
+
- Added CLI commands for Redis compatibility checks, queue statistics, message
|
|
43
|
+
publish, consume with optional ack/nack/retry, delayed scheduling, due
|
|
44
|
+
release, and dead-letter inspection.
|
|
45
|
+
- Added deterministic JSON CLI output and user-facing JSON validation errors.
|
|
46
|
+
- Added CLI unit tests with injected fake Redis and queue clients.
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- Normalized `BRPOPLPUSH` timeout values to integer seconds for Redis versions
|
|
51
|
+
older than 6.2, improving Redis 5.x List consume compatibility.
|
|
52
|
+
|
|
53
|
+
### 新增
|
|
54
|
+
|
|
55
|
+
- 新增 `redqueue` CLI 和 `python -m redqueue` 模块入口,方便开发者调试。
|
|
56
|
+
- 新增 Redis 兼容性检查、队列统计、消息发布、消费并可选 ack/nack/retry、
|
|
57
|
+
延迟调度、到期释放和死信查看命令。
|
|
58
|
+
- CLI 输出稳定 JSON,并提供面向用户的 JSON 参数校验错误。
|
|
59
|
+
- 新增基于 fake Redis 和 fake queue client 的 CLI 单元测试。
|
|
60
|
+
|
|
61
|
+
### 修复
|
|
62
|
+
|
|
63
|
+
- 对 Redis 6.2 以下版本使用 `BRPOPLPUSH` 时,将 timeout 规范为整数秒,
|
|
64
|
+
提升 Redis 5.x List 消费兼容性。
|
|
65
|
+
|
|
66
|
+
## [0.11.2] - 2026-06-21
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- Fixed cleanup for directly constructed sync clients when owned Redis backend
|
|
71
|
+
initialization fails.
|
|
72
|
+
- Fixed cleanup for directly constructed async clients when lazy backend
|
|
73
|
+
initialization fails.
|
|
74
|
+
- Made sync and async client `close()` idempotent for owned Redis clients.
|
|
75
|
+
|
|
76
|
+
### 修复
|
|
77
|
+
|
|
78
|
+
- 修复直接构造同步客户端时,如果 owned Redis 的后端初始化失败,Redis client
|
|
79
|
+
未释放的问题。
|
|
80
|
+
- 修复直接构造异步客户端时,如果懒加载后端初始化失败,Redis client 未释放的问题。
|
|
81
|
+
- 同步和异步客户端的 `close()` 对 owned Redis client 变为幂等。
|
|
82
|
+
|
|
83
|
+
## [0.11.1] - 2026-06-21
|
|
28
84
|
|
|
29
85
|
### Fixed
|
|
30
86
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redqueue
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: Redis-backed Python message queue library with List, Streams, delayed tasks, and monitoring.
|
|
5
5
|
Project-URL: Homepage, https://github.com/SpringMirror-pear/redqueue
|
|
6
6
|
Project-URL: Repository, https://github.com/SpringMirror-pear/redqueue.git
|
|
@@ -50,6 +50,8 @@ https://github.com/SpringMirror-pear/redqueue.git
|
|
|
50
50
|
- Delayed tasks based on Redis Sorted Set.
|
|
51
51
|
- Sync client `QueueClient` and async client `AsyncQueueClient`.
|
|
52
52
|
- Redis connection pool managers for shared sync and async resources.
|
|
53
|
+
- `redqueue` CLI for local debugging and operational checks.
|
|
54
|
+
- First-class `trace_id` propagation for lifecycle tracing.
|
|
53
55
|
- Unified exception hierarchy with structured context.
|
|
54
56
|
- Monitoring events for publish, consume, ack, nack, retry, dead letter, delay,
|
|
55
57
|
and backend errors.
|
|
@@ -80,18 +82,63 @@ Redis:
|
|
|
80
82
|
pip install redqueue
|
|
81
83
|
```
|
|
82
84
|
|
|
85
|
+
The package installs a `redqueue` command. You can also run it with
|
|
86
|
+
`python -m redqueue` from a source checkout.
|
|
87
|
+
|
|
83
88
|
For local development:
|
|
84
89
|
|
|
85
90
|
```bash
|
|
86
91
|
python -m pip install -r requirements.txt
|
|
87
92
|
```
|
|
88
93
|
|
|
94
|
+
## CLI
|
|
95
|
+
|
|
96
|
+
Check Redis compatibility:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
redqueue check --url redis://127.0.0.1:6379/0
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Inspect queue counts:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
redqueue stats --url redis://127.0.0.1:6379/0 --queue emails
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Publish and consume messages:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
redqueue publish --queue emails --payload '{"to":"user@example.com"}'
|
|
112
|
+
redqueue consume --queue emails --timeout 1 --ack
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Publish with trace correlation:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
redqueue publish --queue emails --payload '{"to":"user@example.com"}' --trace-id trace-123
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Delayed task debugging:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
redqueue delay --queue emails --payload '{"to":"later@example.com"}' --delay-seconds 60
|
|
125
|
+
redqueue schedule-due --queue emails --limit 100
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Dead-letter inspection:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
redqueue dead-letters --queue emails --limit 20
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
All command output is JSON so it can be piped into scripts or log processors.
|
|
135
|
+
|
|
89
136
|
## Quick Start
|
|
90
137
|
|
|
91
138
|
Synchronous List queue:
|
|
92
139
|
|
|
93
140
|
```python
|
|
94
|
-
from redqueue import QueueClient
|
|
141
|
+
from redqueue import QueueClient, new_trace_id
|
|
95
142
|
|
|
96
143
|
client = QueueClient.from_url(
|
|
97
144
|
"redis://127.0.0.1:6379/0",
|
|
@@ -99,11 +146,13 @@ client = QueueClient.from_url(
|
|
|
99
146
|
backend="list",
|
|
100
147
|
)
|
|
101
148
|
|
|
102
|
-
|
|
149
|
+
trace_id = new_trace_id()
|
|
150
|
+
message_id = client.publish({"to": "user@example.com"}, trace_id=trace_id)
|
|
103
151
|
message = client.consume(timeout=1)
|
|
104
152
|
|
|
105
153
|
if message is not None:
|
|
106
154
|
try:
|
|
155
|
+
print(message.trace_id)
|
|
107
156
|
print(message.payload)
|
|
108
157
|
client.ack(message)
|
|
109
158
|
except Exception:
|
|
@@ -157,10 +206,30 @@ Delayed task:
|
|
|
157
206
|
from redqueue import QueueClient
|
|
158
207
|
|
|
159
208
|
client = QueueClient.from_url("redis://127.0.0.1:6379/0", queue="emails")
|
|
160
|
-
client.delay({"to": "later@example.com"}, delay_seconds=60)
|
|
209
|
+
client.delay({"to": "later@example.com"}, delay_seconds=60, trace_id="trace-123")
|
|
161
210
|
released = client.schedule_due(limit=100)
|
|
162
211
|
```
|
|
163
212
|
|
|
213
|
+
Trace IDs:
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from redqueue import InMemoryMonitoringHook, QueueClient, new_trace_id
|
|
217
|
+
|
|
218
|
+
hook = InMemoryMonitoringHook()
|
|
219
|
+
client = QueueClient.from_url(
|
|
220
|
+
"redis://127.0.0.1:6379/0",
|
|
221
|
+
queue="emails",
|
|
222
|
+
monitoring=hook,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
trace_id = new_trace_id()
|
|
226
|
+
client.publish({"to": "user@example.com"}, trace_id=trace_id)
|
|
227
|
+
message = client.consume(timeout=1)
|
|
228
|
+
|
|
229
|
+
assert message.trace_id == trace_id
|
|
230
|
+
assert hook.events[-1].trace_id == trace_id
|
|
231
|
+
```
|
|
232
|
+
|
|
164
233
|
Connection pool management:
|
|
165
234
|
|
|
166
235
|
```python
|
|
@@ -14,9 +14,11 @@ https://github.com/SpringMirror-pear/redqueue.git
|
|
|
14
14
|
`BRPOPLPUSH`。
|
|
15
15
|
- 基于 Redis Streams 的消费组后端,Streams 要求 Redis `>=5.0`。
|
|
16
16
|
- 基于 Redis Sorted Set 的延迟任务。
|
|
17
|
-
- 同步客户端 `QueueClient` 与异步客户端 `AsyncQueueClient`。
|
|
18
|
-
- 支持同步和异步 Redis 连接池管理器,方便多个客户端共享连接池。
|
|
19
|
-
-
|
|
17
|
+
- 同步客户端 `QueueClient` 与异步客户端 `AsyncQueueClient`。
|
|
18
|
+
- 支持同步和异步 Redis 连接池管理器,方便多个客户端共享连接池。
|
|
19
|
+
- 提供 `redqueue` CLI,用于本地调试和运行时检查。
|
|
20
|
+
- 一等 `trace_id` 链路追踪能力,贯穿消息生命周期。
|
|
21
|
+
- 带结构化上下文的统一异常体系。
|
|
20
22
|
- 针对发布、消费、确认、拒绝、重试、死信、延迟和后端错误的监控事件。
|
|
21
23
|
- 通过 `INFO server` 探测 Redis 能力。
|
|
22
24
|
- Apache License 2.0。
|
|
@@ -45,18 +47,63 @@ Redis:
|
|
|
45
47
|
pip install redqueue
|
|
46
48
|
```
|
|
47
49
|
|
|
50
|
+
安装后会提供 `redqueue` 命令。从源码目录调试时也可以使用
|
|
51
|
+
`python -m redqueue`。
|
|
52
|
+
|
|
48
53
|
本地开发:
|
|
49
54
|
|
|
50
55
|
```bash
|
|
51
56
|
python -m pip install -r requirements.txt
|
|
52
57
|
```
|
|
53
58
|
|
|
59
|
+
## CLI
|
|
60
|
+
|
|
61
|
+
检查 Redis 兼容性:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
redqueue check --url redis://127.0.0.1:6379/0
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
查看队列统计:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
redqueue stats --url redis://127.0.0.1:6379/0 --queue emails
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
发布和消费消息:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
redqueue publish --queue emails --payload '{"to":"user@example.com"}'
|
|
77
|
+
redqueue consume --queue emails --timeout 1 --ack
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
发布时指定 trace:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
redqueue publish --queue emails --payload '{"to":"user@example.com"}' --trace-id trace-123
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
调试延迟任务:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
redqueue delay --queue emails --payload '{"to":"later@example.com"}' --delay-seconds 60
|
|
90
|
+
redqueue schedule-due --queue emails --limit 100
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
查看死信:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
redqueue dead-letters --queue emails --limit 20
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
所有命令都输出 JSON,方便接入脚本和日志处理流程。
|
|
100
|
+
|
|
54
101
|
## 快速开始
|
|
55
102
|
|
|
56
103
|
同步 List 队列:
|
|
57
104
|
|
|
58
|
-
```python
|
|
59
|
-
from redqueue import QueueClient
|
|
105
|
+
```python
|
|
106
|
+
from redqueue import QueueClient, new_trace_id
|
|
60
107
|
|
|
61
108
|
client = QueueClient.from_url(
|
|
62
109
|
"redis://127.0.0.1:6379/0",
|
|
@@ -64,13 +111,15 @@ client = QueueClient.from_url(
|
|
|
64
111
|
backend="list",
|
|
65
112
|
)
|
|
66
113
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
114
|
+
trace_id = new_trace_id()
|
|
115
|
+
message_id = client.publish({"to": "user@example.com"}, trace_id=trace_id)
|
|
116
|
+
message = client.consume(timeout=1)
|
|
117
|
+
|
|
118
|
+
if message is not None:
|
|
119
|
+
try:
|
|
120
|
+
print(message.trace_id)
|
|
121
|
+
print(message.payload)
|
|
122
|
+
client.ack(message)
|
|
74
123
|
except Exception:
|
|
75
124
|
client.retry(message, reason="handler failed")
|
|
76
125
|
```
|
|
@@ -121,10 +170,30 @@ asyncio.run(main())
|
|
|
121
170
|
```python
|
|
122
171
|
from redqueue import QueueClient
|
|
123
172
|
|
|
124
|
-
client = QueueClient.from_url("redis://127.0.0.1:6379/0", queue="emails")
|
|
125
|
-
client.delay({"to": "later@example.com"}, delay_seconds=60)
|
|
126
|
-
released = client.schedule_due(limit=100)
|
|
127
|
-
```
|
|
173
|
+
client = QueueClient.from_url("redis://127.0.0.1:6379/0", queue="emails")
|
|
174
|
+
client.delay({"to": "later@example.com"}, delay_seconds=60, trace_id="trace-123")
|
|
175
|
+
released = client.schedule_due(limit=100)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
链路追踪:
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from redqueue import InMemoryMonitoringHook, QueueClient, new_trace_id
|
|
182
|
+
|
|
183
|
+
hook = InMemoryMonitoringHook()
|
|
184
|
+
client = QueueClient.from_url(
|
|
185
|
+
"redis://127.0.0.1:6379/0",
|
|
186
|
+
queue="emails",
|
|
187
|
+
monitoring=hook,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
trace_id = new_trace_id()
|
|
191
|
+
client.publish({"to": "user@example.com"}, trace_id=trace_id)
|
|
192
|
+
message = client.consume(timeout=1)
|
|
193
|
+
|
|
194
|
+
assert message.trace_id == trace_id
|
|
195
|
+
assert hook.events[-1].trace_id == trace_id
|
|
196
|
+
```
|
|
128
197
|
|
|
129
198
|
连接池管理:
|
|
130
199
|
|
|
@@ -15,9 +15,11 @@ https://github.com/SpringMirror-pear/redqueue.git
|
|
|
15
15
|
fallback on older compatible Redis versions.
|
|
16
16
|
- Redis Streams backend with consumer groups. Streams require Redis `>=5.0`.
|
|
17
17
|
- Delayed tasks based on Redis Sorted Set.
|
|
18
|
-
- Sync client `QueueClient` and async client `AsyncQueueClient`.
|
|
19
|
-
- Redis connection pool managers for shared sync and async resources.
|
|
20
|
-
-
|
|
18
|
+
- Sync client `QueueClient` and async client `AsyncQueueClient`.
|
|
19
|
+
- Redis connection pool managers for shared sync and async resources.
|
|
20
|
+
- `redqueue` CLI for local debugging and operational checks.
|
|
21
|
+
- First-class `trace_id` propagation for lifecycle tracing.
|
|
22
|
+
- Unified exception hierarchy with structured context.
|
|
21
23
|
- Monitoring events for publish, consume, ack, nack, retry, dead letter, delay,
|
|
22
24
|
and backend errors.
|
|
23
25
|
- Redis capability detection from `INFO server`.
|
|
@@ -47,18 +49,63 @@ Redis:
|
|
|
47
49
|
pip install redqueue
|
|
48
50
|
```
|
|
49
51
|
|
|
52
|
+
The package installs a `redqueue` command. You can also run it with
|
|
53
|
+
`python -m redqueue` from a source checkout.
|
|
54
|
+
|
|
50
55
|
For local development:
|
|
51
56
|
|
|
52
57
|
```bash
|
|
53
58
|
python -m pip install -r requirements.txt
|
|
54
59
|
```
|
|
55
60
|
|
|
61
|
+
## CLI
|
|
62
|
+
|
|
63
|
+
Check Redis compatibility:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
redqueue check --url redis://127.0.0.1:6379/0
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Inspect queue counts:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
redqueue stats --url redis://127.0.0.1:6379/0 --queue emails
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Publish and consume messages:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
redqueue publish --queue emails --payload '{"to":"user@example.com"}'
|
|
79
|
+
redqueue consume --queue emails --timeout 1 --ack
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Publish with trace correlation:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
redqueue publish --queue emails --payload '{"to":"user@example.com"}' --trace-id trace-123
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Delayed task debugging:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
redqueue delay --queue emails --payload '{"to":"later@example.com"}' --delay-seconds 60
|
|
92
|
+
redqueue schedule-due --queue emails --limit 100
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Dead-letter inspection:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
redqueue dead-letters --queue emails --limit 20
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
All command output is JSON so it can be piped into scripts or log processors.
|
|
102
|
+
|
|
56
103
|
## Quick Start
|
|
57
104
|
|
|
58
105
|
Synchronous List queue:
|
|
59
106
|
|
|
60
|
-
```python
|
|
61
|
-
from redqueue import QueueClient
|
|
107
|
+
```python
|
|
108
|
+
from redqueue import QueueClient, new_trace_id
|
|
62
109
|
|
|
63
110
|
client = QueueClient.from_url(
|
|
64
111
|
"redis://127.0.0.1:6379/0",
|
|
@@ -66,13 +113,15 @@ client = QueueClient.from_url(
|
|
|
66
113
|
backend="list",
|
|
67
114
|
)
|
|
68
115
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
116
|
+
trace_id = new_trace_id()
|
|
117
|
+
message_id = client.publish({"to": "user@example.com"}, trace_id=trace_id)
|
|
118
|
+
message = client.consume(timeout=1)
|
|
119
|
+
|
|
120
|
+
if message is not None:
|
|
121
|
+
try:
|
|
122
|
+
print(message.trace_id)
|
|
123
|
+
print(message.payload)
|
|
124
|
+
client.ack(message)
|
|
76
125
|
except Exception:
|
|
77
126
|
client.retry(message, reason="handler failed")
|
|
78
127
|
```
|
|
@@ -123,10 +172,30 @@ Delayed task:
|
|
|
123
172
|
```python
|
|
124
173
|
from redqueue import QueueClient
|
|
125
174
|
|
|
126
|
-
client = QueueClient.from_url("redis://127.0.0.1:6379/0", queue="emails")
|
|
127
|
-
client.delay({"to": "later@example.com"}, delay_seconds=60)
|
|
128
|
-
released = client.schedule_due(limit=100)
|
|
129
|
-
```
|
|
175
|
+
client = QueueClient.from_url("redis://127.0.0.1:6379/0", queue="emails")
|
|
176
|
+
client.delay({"to": "later@example.com"}, delay_seconds=60, trace_id="trace-123")
|
|
177
|
+
released = client.schedule_due(limit=100)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Trace IDs:
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
from redqueue import InMemoryMonitoringHook, QueueClient, new_trace_id
|
|
184
|
+
|
|
185
|
+
hook = InMemoryMonitoringHook()
|
|
186
|
+
client = QueueClient.from_url(
|
|
187
|
+
"redis://127.0.0.1:6379/0",
|
|
188
|
+
queue="emails",
|
|
189
|
+
monitoring=hook,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
trace_id = new_trace_id()
|
|
193
|
+
client.publish({"to": "user@example.com"}, trace_id=trace_id)
|
|
194
|
+
message = client.consume(timeout=1)
|
|
195
|
+
|
|
196
|
+
assert message.trace_id == trace_id
|
|
197
|
+
assert hook.events[-1].trace_id == trace_id
|
|
198
|
+
```
|
|
130
199
|
|
|
131
200
|
Connection pool management:
|
|
132
201
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# RedQueue API / RedQueue API 文档
|
|
2
2
|
|
|
3
|
-
This document describes the public API available in RedQueue `0.
|
|
3
|
+
This document describes the public API available in RedQueue `0.13.0`.
|
|
4
4
|
|
|
5
|
-
本文档描述 RedQueue `0.
|
|
5
|
+
本文档描述 RedQueue `0.13.0` 的公开 API。
|
|
6
6
|
|
|
7
7
|
## Clients / 客户端
|
|
8
8
|
|
|
@@ -27,12 +27,12 @@ Methods / 方法:
|
|
|
27
27
|
- `from_url(url, *, queue, backend="list", connection_manager=None, **options) -> QueueClient`
|
|
28
28
|
- Advanced options include `pool_options`, injected `redis`, injected
|
|
29
29
|
`capabilities`, and `owns_redis`.
|
|
30
|
-
- `publish(payload, *, delay=None, headers=None, message_id=None) -> str`
|
|
30
|
+
- `publish(payload, *, delay=None, headers=None, message_id=None, trace_id=None) -> str`
|
|
31
31
|
- `consume(*, timeout=None, batch_size=1) -> Message | list[Message] | None`
|
|
32
32
|
- `ack(message) -> None`
|
|
33
33
|
- `nack(message, *, requeue=True) -> None`
|
|
34
34
|
- `retry(message, *, delay=None, reason=None) -> None`
|
|
35
|
-
- `delay(payload, *, delay_seconds=None, run_at=None, headers=None) -> str`
|
|
35
|
+
- `delay(payload, *, delay_seconds=None, run_at=None, headers=None, trace_id=None) -> str`
|
|
36
36
|
- `schedule_due(*, limit=100, now=None) -> int`
|
|
37
37
|
- `recover_stale(*, min_idle_ms=None, limit=100) -> int`
|
|
38
38
|
- `dead_letters(*, limit=100) -> list[Message]`
|
|
@@ -61,12 +61,12 @@ Methods / 方法:
|
|
|
61
61
|
- `await from_url(url, *, queue, backend="list", connection_manager=None, **options) -> AsyncQueueClient`
|
|
62
62
|
- Advanced options include `pool_options`, injected `redis`, injected
|
|
63
63
|
`capabilities`, and `owns_redis`.
|
|
64
|
-
- `await publish(payload, *, delay=None, headers=None, message_id=None) -> str`
|
|
64
|
+
- `await publish(payload, *, delay=None, headers=None, message_id=None, trace_id=None) -> str`
|
|
65
65
|
- `await consume(*, timeout=None, batch_size=1) -> Message | list[Message] | None`
|
|
66
66
|
- `await ack(message) -> None`
|
|
67
67
|
- `await nack(message, *, requeue=True) -> None`
|
|
68
68
|
- `await retry(message, *, delay=None, reason=None) -> None`
|
|
69
|
-
- `await delay(payload, *, delay_seconds=None, run_at=None, headers=None) -> str`
|
|
69
|
+
- `await delay(payload, *, delay_seconds=None, run_at=None, headers=None, trace_id=None) -> str`
|
|
70
70
|
- `await schedule_due(*, limit=100, now=None) -> int`
|
|
71
71
|
- `await recover_stale(*, min_idle_ms=None, limit=100) -> int`
|
|
72
72
|
- `await dead_letters(*, limit=100) -> list[Message]`
|
|
@@ -188,9 +188,10 @@ Fields / 字段:
|
|
|
188
188
|
|
|
189
189
|
- `id: str`
|
|
190
190
|
- `queue: str`
|
|
191
|
-
- `payload: Any`
|
|
192
|
-
- `headers: dict[str, Any]`
|
|
193
|
-
- `
|
|
191
|
+
- `payload: Any`
|
|
192
|
+
- `headers: dict[str, Any]`
|
|
193
|
+
- `trace_id: str | None`
|
|
194
|
+
- `attempts: int`
|
|
194
195
|
- `created_at: float`
|
|
195
196
|
- `available_at: float | None`
|
|
196
197
|
- `backend: str | None`
|
|
@@ -199,9 +200,32 @@ Fields / 字段:
|
|
|
199
200
|
|
|
200
201
|
Helpers / 辅助方法:
|
|
201
202
|
|
|
202
|
-
- `with_attempt() -> Message`
|
|
203
|
-
- `with_backend(backend, *, raw_id=None, raw_payload=None) -> Message`
|
|
204
|
-
- `new_message_id() -> str`
|
|
203
|
+
- `with_attempt() -> Message`
|
|
204
|
+
- `with_backend(backend, *, raw_id=None, raw_payload=None) -> Message`
|
|
205
|
+
- `new_message_id() -> str`
|
|
206
|
+
- `new_trace_id() -> str`
|
|
207
|
+
|
|
208
|
+
## Trace IDs / 链路追踪
|
|
209
|
+
|
|
210
|
+
`trace_id` is an optional lifecycle correlation id. It can be supplied to
|
|
211
|
+
`publish()` or `delay()`, is mirrored into `Message.headers["trace_id"]`, and is
|
|
212
|
+
preserved through consume, ack, nack, retry, delayed release, dead-letter, and
|
|
213
|
+
requeue flows.
|
|
214
|
+
|
|
215
|
+
`trace_id` 是可选的生命周期关联 ID。可以在 `publish()` 或 `delay()` 中传入,
|
|
216
|
+
会同步写入 `Message.headers["trace_id"]`,并在消费、ack、nack、retry、
|
|
217
|
+
延迟释放、死信和重放流程中保持传递。
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
from redqueue import QueueClient, new_trace_id
|
|
221
|
+
|
|
222
|
+
client = QueueClient.from_url("redis://127.0.0.1:6379/0", queue="emails")
|
|
223
|
+
trace_id = new_trace_id()
|
|
224
|
+
client.publish({"to": "user@example.com"}, trace_id=trace_id)
|
|
225
|
+
message = client.consume(timeout=1)
|
|
226
|
+
|
|
227
|
+
assert message.trace_id == trace_id
|
|
228
|
+
```
|
|
205
229
|
|
|
206
230
|
## Backends / 后端
|
|
207
231
|
|
|
@@ -299,9 +323,13 @@ All RedQueue custom exceptions inherit from `RedQueueError`.
|
|
|
299
323
|
- `CompositeMonitoringHook`
|
|
300
324
|
- `SafeMonitoringHook`
|
|
301
325
|
|
|
302
|
-
Monitoring events do not include business payload by default.
|
|
303
|
-
|
|
304
|
-
监控事件默认不包含业务 payload。
|
|
326
|
+
Monitoring events do not include business payload by default.
|
|
327
|
+
|
|
328
|
+
监控事件默认不包含业务 payload。
|
|
329
|
+
|
|
330
|
+
Monitoring events include `trace_id` when a message operation has one.
|
|
331
|
+
|
|
332
|
+
消息操作存在 `trace_id` 时,监控事件会包含该字段。
|
|
305
333
|
|
|
306
334
|
## Redis Capability Detection / Redis 能力探测
|
|
307
335
|
|
|
@@ -314,3 +342,35 @@ Monitoring events do not include business payload by default.
|
|
|
314
342
|
Streams are rejected with `RedisCompatibilityError` when Redis is below `5.0`.
|
|
315
343
|
|
|
316
344
|
当 Redis 低于 `5.0` 时,启用 Streams 会抛出 `RedisCompatibilityError`。
|
|
345
|
+
|
|
346
|
+
## CLI / 命令行工具
|
|
347
|
+
|
|
348
|
+
RedQueue `0.13.0` provides a `redqueue` console command and a
|
|
349
|
+
`python -m redqueue` module entry point for developer diagnostics.
|
|
350
|
+
|
|
351
|
+
RedQueue `0.13.0` 提供 `redqueue` 控制台命令和 `python -m redqueue`
|
|
352
|
+
模块入口,用于开发者调试。
|
|
353
|
+
|
|
354
|
+
Commands / 命令:
|
|
355
|
+
|
|
356
|
+
- `redqueue check --url redis://127.0.0.1:6379/0`
|
|
357
|
+
- `redqueue stats --queue emails [--backend list|stream]`
|
|
358
|
+
- `redqueue publish --queue emails --payload '{"to":"user@example.com"}' [--trace-id trace-123]`
|
|
359
|
+
- `redqueue consume --queue emails [--ack|--nack|--retry]`
|
|
360
|
+
- `redqueue delay --queue emails --payload '{"to":"later@example.com"}' --delay-seconds 60 [--trace-id trace-123]`
|
|
361
|
+
- `redqueue schedule-due --queue emails --limit 100`
|
|
362
|
+
- `redqueue dead-letters --queue emails --limit 20`
|
|
363
|
+
|
|
364
|
+
Common options / 通用选项:
|
|
365
|
+
|
|
366
|
+
- `--url`: Redis URL. Defaults to `redis://127.0.0.1:6379/0`.
|
|
367
|
+
- `--queue`: RedQueue queue name.
|
|
368
|
+
- `--backend`: `list` or `stream`.
|
|
369
|
+
- `--namespace`: Redis key namespace. Defaults to `rq`.
|
|
370
|
+
- `--consumer-group`: Streams consumer group. Defaults to `redqueue`.
|
|
371
|
+
- `--consumer-name`: Optional Streams consumer name.
|
|
372
|
+
- `--trace-id`: Optional trace id for `publish` and `delay`.
|
|
373
|
+
|
|
374
|
+
Payload and headers are JSON strings. Command responses are stable JSON objects.
|
|
375
|
+
|
|
376
|
+
Payload 和 headers 使用 JSON 字符串。命令响应为稳定 JSON 对象。
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "redqueue"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.13.0"
|
|
8
8
|
description = "Redis-backed Python message queue library with List, Streams, delayed tasks, and monitoring."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -38,6 +38,9 @@ Homepage = "https://github.com/SpringMirror-pear/redqueue"
|
|
|
38
38
|
Repository = "https://github.com/SpringMirror-pear/redqueue.git"
|
|
39
39
|
Issues = "https://github.com/SpringMirror-pear/redqueue/issues"
|
|
40
40
|
|
|
41
|
+
[project.scripts]
|
|
42
|
+
redqueue = "redqueue.cli:main"
|
|
43
|
+
|
|
41
44
|
[project.optional-dependencies]
|
|
42
45
|
dev = [
|
|
43
46
|
"pytest==9.1.1; python_version >= '3.10'",
|
|
@@ -26,7 +26,7 @@ from redqueue.exceptions import (
|
|
|
26
26
|
RedQueueError,
|
|
27
27
|
RetryExceededError,
|
|
28
28
|
)
|
|
29
|
-
from redqueue.message import Message, new_message_id
|
|
29
|
+
from redqueue.message import Message, new_message_id, new_trace_id
|
|
30
30
|
from redqueue.monitoring import (
|
|
31
31
|
CompositeMonitoringHook,
|
|
32
32
|
InMemoryMonitoringHook,
|
|
@@ -71,5 +71,6 @@ __all__ = [
|
|
|
71
71
|
"detect_capabilities",
|
|
72
72
|
"detect_capabilities_async",
|
|
73
73
|
"extract_redis_version",
|
|
74
|
-
"new_message_id",
|
|
75
|
-
|
|
74
|
+
"new_message_id",
|
|
75
|
+
"new_trace_id",
|
|
76
|
+
]
|