rrq 0.7.1__tar.gz → 0.8.1__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.
- rrq-0.8.1/AGENTS.md +32 -0
- rrq-0.8.1/CLAUDE.md +32 -0
- {rrq-0.7.1 → rrq-0.8.1}/PKG-INFO +49 -5
- {rrq-0.7.1 → rrq-0.8.1}/README.md +46 -4
- {rrq-0.7.1 → rrq-0.8.1}/example/rrq_example.py +10 -15
- {rrq-0.7.1 → rrq-0.8.1}/pyproject.toml +8 -8
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli.py +5 -3
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/base.py +4 -1
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/commands/debug.py +2 -2
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/commands/monitor.py +92 -60
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/commands/queues.py +2 -2
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/utils.py +5 -4
- rrq-0.8.1/rrq/client.py +196 -0
- rrq-0.8.1/rrq/exporters/__init__.py +1 -0
- rrq-0.8.1/rrq/exporters/prometheus.py +90 -0
- rrq-0.8.1/rrq/exporters/statsd.py +60 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/hooks.py +80 -47
- rrq-0.8.1/rrq/integrations/__init__.py +1 -0
- rrq-0.8.1/rrq/integrations/ddtrace.py +456 -0
- rrq-0.8.1/rrq/integrations/logfire.py +23 -0
- rrq-0.8.1/rrq/integrations/otel.py +325 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/job.py +6 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/settings.py +2 -2
- {rrq-0.7.1 → rrq-0.8.1}/rrq/store.py +49 -6
- rrq-0.8.1/rrq/telemetry.py +129 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/worker.py +259 -94
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/conftest.py +5 -8
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/test_debug_commands.py +7 -4
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/test_dlq_commands.py +1 -0
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/test_integration.py +5 -5
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/test_job_commands.py +1 -0
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/test_monitor_commands.py +18 -10
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/test_queue_commands.py +1 -0
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/test_queue_dlq_integration.py +1 -0
- {rrq-0.7.1 → rrq-0.8.1}/tests/test_cli.py +6 -1
- {rrq-0.7.1 → rrq-0.8.1}/tests/test_client.py +55 -14
- {rrq-0.7.1 → rrq-0.8.1}/tests/test_cron.py +6 -2
- {rrq-0.7.1 → rrq-0.8.1}/tests/test_registry.py +3 -1
- {rrq-0.7.1 → rrq-0.8.1}/tests/test_store.py +87 -2
- {rrq-0.7.1 → rrq-0.8.1}/tests/test_worker.py +56 -13
- rrq-0.8.1/uv.lock +740 -0
- rrq-0.7.1/CLAUDE.md +0 -115
- rrq-0.7.1/rrq/client.py +0 -186
- rrq-0.7.1/uv.lock +0 -724
- {rrq-0.7.1 → rrq-0.8.1}/.coverage +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/.github/workflows/ci.yml +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/.gitignore +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/LICENSE +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/MANIFEST.in +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/docs/CLI_REFERENCE.md +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/example/example_rrq_settings.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/__init__.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/__init__.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/commands/__init__.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/commands/dlq.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cli_commands/commands/jobs.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/constants.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/cron.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/exc.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/rrq/registry.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/tests/CLAUDE.md +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/tests/__init__.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/__init__.py +0 -0
- {rrq-0.7.1 → rrq-0.8.1}/tests/cli_commands/test_monitor_dlq_integration.py +0 -0
rrq-0.8.1/AGENTS.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# RRQ
|
|
2
|
+
|
|
3
|
+
Redis-based async job queue library for Python.
|
|
4
|
+
|
|
5
|
+
See @tests/CLAUDE.md for testing guidelines.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
```bash
|
|
9
|
+
uv run pytest # Run tests
|
|
10
|
+
uv run pytest --maxfail=1 # Debug failing tests
|
|
11
|
+
uv run ruff format && uv run ruff check --fix # Format and lint (run before commits)
|
|
12
|
+
uv run ty check # Type check (must pass before commits)
|
|
13
|
+
uv add <package> # Add dependency
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Code Style
|
|
17
|
+
- Python 3.11+, double quotes, 88 char lines
|
|
18
|
+
- Type hints on all functions, Pydantic V2 for validation
|
|
19
|
+
- `snake_case` functions, `PascalCase` classes
|
|
20
|
+
- Import order: stdlib → third-party → local
|
|
21
|
+
- Early returns, `match/case` for complex conditionals
|
|
22
|
+
- No blocking I/O in async contexts
|
|
23
|
+
|
|
24
|
+
## Code References
|
|
25
|
+
Use VS Code clickable format: `rrq/queue.py:45` or `rrq/worker.py:120-135`
|
|
26
|
+
|
|
27
|
+
## Rules
|
|
28
|
+
- Never commit broken tests
|
|
29
|
+
- Use `uv` for all Python operations
|
|
30
|
+
- Follow existing patterns in codebase
|
|
31
|
+
- No sensitive data in logs
|
|
32
|
+
- Ask before large cross-domain changes
|
rrq-0.8.1/CLAUDE.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# RRQ
|
|
2
|
+
|
|
3
|
+
Redis-based async job queue library for Python.
|
|
4
|
+
|
|
5
|
+
See @tests/CLAUDE.md for testing guidelines.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
```bash
|
|
9
|
+
uv run pytest # Run tests
|
|
10
|
+
uv run pytest --maxfail=1 # Debug failing tests
|
|
11
|
+
uv run ruff format && uv run ruff check --fix # Format and lint (run before commits)
|
|
12
|
+
uv run ty check # Type check (must pass before commits)
|
|
13
|
+
uv add <package> # Add dependency
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Code Style
|
|
17
|
+
- Python 3.11+, double quotes, 88 char lines
|
|
18
|
+
- Type hints on all functions, Pydantic V2 for validation
|
|
19
|
+
- `snake_case` functions, `PascalCase` classes
|
|
20
|
+
- Import order: stdlib → third-party → local
|
|
21
|
+
- Early returns, `match/case` for complex conditionals
|
|
22
|
+
- No blocking I/O in async contexts
|
|
23
|
+
|
|
24
|
+
## Code References
|
|
25
|
+
Use VS Code clickable format: `rrq/queue.py:45` or `rrq/worker.py:120-135`
|
|
26
|
+
|
|
27
|
+
## Rules
|
|
28
|
+
- Never commit broken tests
|
|
29
|
+
- Use `uv` for all Python operations
|
|
30
|
+
- Follow existing patterns in codebase
|
|
31
|
+
- No sensitive data in logs
|
|
32
|
+
- Ask before large cross-domain changes
|
{rrq-0.7.1 → rrq-0.8.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rrq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: RRQ is a Python library for creating reliable job queues using Redis and asyncio
|
|
5
5
|
Project-URL: Homepage, https://github.com/getresq/rrq
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/getresq/rrq/issues
|
|
@@ -26,23 +26,30 @@ Provides-Extra: dev
|
|
|
26
26
|
Requires-Dist: pytest-asyncio>=1.0.0; extra == 'dev'
|
|
27
27
|
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
|
|
28
28
|
Requires-Dist: pytest>=8.3.5; extra == 'dev'
|
|
29
|
+
Requires-Dist: ruff==0.14.9; extra == 'dev'
|
|
30
|
+
Requires-Dist: ty==0.0.1-alpha.26; extra == 'dev'
|
|
29
31
|
Description-Content-Type: text/markdown
|
|
30
32
|
|
|
31
33
|
# RRQ: Reliable Redis Queue
|
|
32
34
|
|
|
33
35
|
RRQ is a Python library for creating reliable job queues using Redis and `asyncio`, inspired by [ARQ (Async Redis Queue)](https://github.com/samuelcolvin/arq). It focuses on providing at-least-once job processing semantics with features like automatic retries, job timeouts, dead-letter queues, and graceful worker shutdown.
|
|
34
36
|
|
|
35
|
-
## 🆕 What's New in v0.
|
|
37
|
+
## 🆕 What's New in v0.8.1
|
|
38
|
+
|
|
39
|
+
- **Distributed Tracing**: One-line integrations for Datadog, OpenTelemetry, and Logfire
|
|
40
|
+
- **Trace Context Propagation**: Automatic trace context from producer to worker
|
|
41
|
+
- **Prometheus & StatsD Exporters**: New metrics exporters for monitoring
|
|
42
|
+
|
|
43
|
+
## What's New in v0.7
|
|
36
44
|
|
|
37
45
|
- **Comprehensive CLI Tools**: 15+ new commands for monitoring, debugging, and management
|
|
38
46
|
- **Real-time Monitoring Dashboard**: Interactive dashboard with `rrq monitor`
|
|
39
47
|
- **Enhanced DLQ Management**: Sophisticated filtering and requeuing capabilities
|
|
40
|
-
- **Python 3.10 Support**: Expanded compatibility from Python 3.11+ to 3.10+
|
|
41
48
|
- **Bug Fixes**: Critical fix for unique job enqueue failures with proper deferral
|
|
42
49
|
|
|
43
50
|
## Requirements
|
|
44
51
|
|
|
45
|
-
- Python 3.
|
|
52
|
+
- Python 3.11 or higher
|
|
46
53
|
- Redis 5.0 or higher
|
|
47
54
|
- asyncio-compatible environment
|
|
48
55
|
|
|
@@ -144,6 +151,8 @@ this purpose.
|
|
|
144
151
|
|
|
145
152
|
```python
|
|
146
153
|
# worker_script.py
|
|
154
|
+
import asyncio
|
|
155
|
+
|
|
147
156
|
from rrq.worker import RRQWorker
|
|
148
157
|
from config import rrq_settings # Import your settings
|
|
149
158
|
from main_setup import job_registry # Import your registry
|
|
@@ -153,7 +162,7 @@ worker = RRQWorker(settings=rrq_settings, job_registry=job_registry)
|
|
|
153
162
|
|
|
154
163
|
# Run the worker (blocking)
|
|
155
164
|
if __name__ == "__main__":
|
|
156
|
-
worker.run()
|
|
165
|
+
asyncio.run(worker.run())
|
|
157
166
|
```
|
|
158
167
|
|
|
159
168
|
You can run multiple instances of `worker_script.py` for concurrent processing.
|
|
@@ -433,6 +442,41 @@ RRQ can be configured in several ways, with the following precedence:
|
|
|
433
442
|
|
|
434
443
|
**Important Note on `job_registry`**: The `job_registry` attribute in your `RRQSettings` object is **critical** for RRQ to function. It must be an instance of `JobRegistry` and is used to register job handlers. Without a properly configured `job_registry`, workers will not know how to process jobs, and most operations will fail. Ensure it is set in your settings object to map job names to their respective handler functions.
|
|
435
444
|
|
|
445
|
+
## Telemetry (Datadog / OTEL / Logfire)
|
|
446
|
+
|
|
447
|
+
RRQ supports optional distributed tracing for enqueue and job execution. Enable the
|
|
448
|
+
integration in both the producer and worker processes to get end-to-end traces
|
|
449
|
+
across the Redis queue.
|
|
450
|
+
|
|
451
|
+
### Datadog (ddtrace)
|
|
452
|
+
|
|
453
|
+
```python
|
|
454
|
+
from rrq.integrations.ddtrace import enable as enable_rrq_ddtrace
|
|
455
|
+
|
|
456
|
+
enable_rrq_ddtrace(service="myapp-rrq")
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
This only instruments RRQ spans + propagation; it does **not** call
|
|
460
|
+
`ddtrace.patch_all()`. Configure `ddtrace` in your app as you already do.
|
|
461
|
+
|
|
462
|
+
### Logfire
|
|
463
|
+
|
|
464
|
+
```python
|
|
465
|
+
import logfire
|
|
466
|
+
from rrq.integrations.logfire import enable as enable_rrq_logfire
|
|
467
|
+
|
|
468
|
+
logfire.configure(service_name="myapp-rrq")
|
|
469
|
+
enable_rrq_logfire(service_name="myapp-rrq")
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### OpenTelemetry (generic)
|
|
473
|
+
|
|
474
|
+
```python
|
|
475
|
+
from rrq.integrations.otel import enable as enable_rrq_otel
|
|
476
|
+
|
|
477
|
+
enable_rrq_otel(service_name="myapp-rrq")
|
|
478
|
+
```
|
|
479
|
+
|
|
436
480
|
### Comprehensive CLI Command System
|
|
437
481
|
- **New modular CLI architecture** with dedicated command modules for better organization
|
|
438
482
|
- **Enhanced monitoring capabilities** with real-time dashboards and beautiful table output
|
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
RRQ is a Python library for creating reliable job queues using Redis and `asyncio`, inspired by [ARQ (Async Redis Queue)](https://github.com/samuelcolvin/arq). It focuses on providing at-least-once job processing semantics with features like automatic retries, job timeouts, dead-letter queues, and graceful worker shutdown.
|
|
4
4
|
|
|
5
|
-
## 🆕 What's New in v0.
|
|
5
|
+
## 🆕 What's New in v0.8.1
|
|
6
|
+
|
|
7
|
+
- **Distributed Tracing**: One-line integrations for Datadog, OpenTelemetry, and Logfire
|
|
8
|
+
- **Trace Context Propagation**: Automatic trace context from producer to worker
|
|
9
|
+
- **Prometheus & StatsD Exporters**: New metrics exporters for monitoring
|
|
10
|
+
|
|
11
|
+
## What's New in v0.7
|
|
6
12
|
|
|
7
13
|
- **Comprehensive CLI Tools**: 15+ new commands for monitoring, debugging, and management
|
|
8
14
|
- **Real-time Monitoring Dashboard**: Interactive dashboard with `rrq monitor`
|
|
9
15
|
- **Enhanced DLQ Management**: Sophisticated filtering and requeuing capabilities
|
|
10
|
-
- **Python 3.10 Support**: Expanded compatibility from Python 3.11+ to 3.10+
|
|
11
16
|
- **Bug Fixes**: Critical fix for unique job enqueue failures with proper deferral
|
|
12
17
|
|
|
13
18
|
## Requirements
|
|
14
19
|
|
|
15
|
-
- Python 3.
|
|
20
|
+
- Python 3.11 or higher
|
|
16
21
|
- Redis 5.0 or higher
|
|
17
22
|
- asyncio-compatible environment
|
|
18
23
|
|
|
@@ -114,6 +119,8 @@ this purpose.
|
|
|
114
119
|
|
|
115
120
|
```python
|
|
116
121
|
# worker_script.py
|
|
122
|
+
import asyncio
|
|
123
|
+
|
|
117
124
|
from rrq.worker import RRQWorker
|
|
118
125
|
from config import rrq_settings # Import your settings
|
|
119
126
|
from main_setup import job_registry # Import your registry
|
|
@@ -123,7 +130,7 @@ worker = RRQWorker(settings=rrq_settings, job_registry=job_registry)
|
|
|
123
130
|
|
|
124
131
|
# Run the worker (blocking)
|
|
125
132
|
if __name__ == "__main__":
|
|
126
|
-
worker.run()
|
|
133
|
+
asyncio.run(worker.run())
|
|
127
134
|
```
|
|
128
135
|
|
|
129
136
|
You can run multiple instances of `worker_script.py` for concurrent processing.
|
|
@@ -403,6 +410,41 @@ RRQ can be configured in several ways, with the following precedence:
|
|
|
403
410
|
|
|
404
411
|
**Important Note on `job_registry`**: The `job_registry` attribute in your `RRQSettings` object is **critical** for RRQ to function. It must be an instance of `JobRegistry` and is used to register job handlers. Without a properly configured `job_registry`, workers will not know how to process jobs, and most operations will fail. Ensure it is set in your settings object to map job names to their respective handler functions.
|
|
405
412
|
|
|
413
|
+
## Telemetry (Datadog / OTEL / Logfire)
|
|
414
|
+
|
|
415
|
+
RRQ supports optional distributed tracing for enqueue and job execution. Enable the
|
|
416
|
+
integration in both the producer and worker processes to get end-to-end traces
|
|
417
|
+
across the Redis queue.
|
|
418
|
+
|
|
419
|
+
### Datadog (ddtrace)
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
from rrq.integrations.ddtrace import enable as enable_rrq_ddtrace
|
|
423
|
+
|
|
424
|
+
enable_rrq_ddtrace(service="myapp-rrq")
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
This only instruments RRQ spans + propagation; it does **not** call
|
|
428
|
+
`ddtrace.patch_all()`. Configure `ddtrace` in your app as you already do.
|
|
429
|
+
|
|
430
|
+
### Logfire
|
|
431
|
+
|
|
432
|
+
```python
|
|
433
|
+
import logfire
|
|
434
|
+
from rrq.integrations.logfire import enable as enable_rrq_logfire
|
|
435
|
+
|
|
436
|
+
logfire.configure(service_name="myapp-rrq")
|
|
437
|
+
enable_rrq_logfire(service_name="myapp-rrq")
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### OpenTelemetry (generic)
|
|
441
|
+
|
|
442
|
+
```python
|
|
443
|
+
from rrq.integrations.otel import enable as enable_rrq_otel
|
|
444
|
+
|
|
445
|
+
enable_rrq_otel(service_name="myapp-rrq")
|
|
446
|
+
```
|
|
447
|
+
|
|
406
448
|
### Comprehensive CLI Command System
|
|
407
449
|
- **New modular CLI architecture** with dedicated command modules for better organization
|
|
408
450
|
- **Enhanced monitoring capabilities** with real-time dashboards and beautiful table output
|
|
@@ -163,18 +163,18 @@ async def main():
|
|
|
163
163
|
_queue_name="high_priority", # Example custom queue
|
|
164
164
|
)
|
|
165
165
|
|
|
166
|
-
if
|
|
167
|
-
logger.info("Jobs enqueued successfully.")
|
|
168
|
-
logger.info(f" - Job 1 (Success): {job1.id}")
|
|
169
|
-
logger.info(f" - Job 2 (Failure): {job2.id}")
|
|
170
|
-
logger.info(f" - Job 3 (Retry): {job3.id}")
|
|
171
|
-
logger.info(f" - Job 4 (Deferred): {job4.id}")
|
|
172
|
-
logger.info(f" - Job 5 (CustomQ): {job5.id}")
|
|
173
|
-
else:
|
|
166
|
+
if job1 is None or job2 is None or job3 is None or job4 is None or job5 is None:
|
|
174
167
|
logger.error("Some jobs failed to enqueue.")
|
|
175
168
|
await client.close()
|
|
176
169
|
return
|
|
177
170
|
|
|
171
|
+
logger.info("Jobs enqueued successfully.")
|
|
172
|
+
logger.info(f" - Job 1 (Success): {job1.id}")
|
|
173
|
+
logger.info(f" - Job 2 (Failure): {job2.id}")
|
|
174
|
+
logger.info(f" - Job 3 (Retry): {job3.id}")
|
|
175
|
+
logger.info(f" - Job 4 (Deferred): {job4.id}")
|
|
176
|
+
logger.info(f" - Job 5 (CustomQ): {job5.id}")
|
|
177
|
+
|
|
178
178
|
await client.close() # Close client connection if no longer needed
|
|
179
179
|
|
|
180
180
|
# 5. Worker Setup
|
|
@@ -247,17 +247,12 @@ async def main():
|
|
|
247
247
|
|
|
248
248
|
async def run_worker_async(worker: RRQWorker):
|
|
249
249
|
"""Helper function to run the worker's main loop asynchronously."""
|
|
250
|
-
# We don't use worker.run() here because it's synchronous.
|
|
251
|
-
# Instead, we directly await the async _run_loop method.
|
|
252
250
|
try:
|
|
253
|
-
await worker.
|
|
251
|
+
await worker.run()
|
|
254
252
|
except Exception as e:
|
|
255
253
|
logger.error(
|
|
256
|
-
f"Worker {worker.worker_id}
|
|
254
|
+
f"Worker {worker.worker_id} run exited with error: {e}", exc_info=True
|
|
257
255
|
)
|
|
258
|
-
finally:
|
|
259
|
-
# Ensure resources are closed even if _run_loop fails unexpectedly
|
|
260
|
-
await worker._close_resources()
|
|
261
256
|
|
|
262
257
|
|
|
263
258
|
if __name__ == "__main__":
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rrq"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.8.1"
|
|
8
8
|
authors = [{ name = "Mazdak Rezvani", email = "mazdak@me.com" }]
|
|
9
9
|
description = "RRQ is a Python library for creating reliable job queues using Redis and asyncio"
|
|
10
10
|
readme = "README.md"
|
|
@@ -31,7 +31,13 @@ dependencies = [
|
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[project.optional-dependencies]
|
|
34
|
-
dev = [
|
|
34
|
+
dev = [
|
|
35
|
+
"pytest>=8.3.5",
|
|
36
|
+
"pytest-asyncio>=1.0.0",
|
|
37
|
+
"pytest-cov>=6.0.0",
|
|
38
|
+
"ruff==0.14.9",
|
|
39
|
+
"ty==0.0.1-alpha.26",
|
|
40
|
+
]
|
|
35
41
|
|
|
36
42
|
[project.urls]
|
|
37
43
|
"Homepage" = "https://github.com/getresq/rrq"
|
|
@@ -43,9 +49,3 @@ rrq = "rrq.cli:rrq"
|
|
|
43
49
|
[tool.pytest.ini_options]
|
|
44
50
|
asyncio_mode = "strict"
|
|
45
51
|
asyncio_default_fixture_loop_scope = "function"
|
|
46
|
-
|
|
47
|
-
[tool.pyrefly]
|
|
48
|
-
python_interpreter = ".venv/bin/python"
|
|
49
|
-
|
|
50
|
-
[dependency-groups]
|
|
51
|
-
dev = []
|
|
@@ -502,7 +502,8 @@ def _run_single_worker(
|
|
|
502
502
|
"""Helper function to run a single RRQ worker instance."""
|
|
503
503
|
rrq_settings = _load_app_settings(settings_object_path)
|
|
504
504
|
|
|
505
|
-
|
|
505
|
+
job_registry = rrq_settings.job_registry
|
|
506
|
+
if job_registry is None:
|
|
506
507
|
click.echo(
|
|
507
508
|
click.style(
|
|
508
509
|
"ERROR: No 'job_registry'. You must provide a JobRegistry instance in settings.",
|
|
@@ -511,15 +512,16 @@ def _run_single_worker(
|
|
|
511
512
|
err=True,
|
|
512
513
|
)
|
|
513
514
|
sys.exit(1)
|
|
515
|
+
assert job_registry is not None
|
|
514
516
|
|
|
515
517
|
logger.debug(
|
|
516
|
-
f"Registered handlers (from effective registry): {
|
|
518
|
+
f"Registered handlers (from effective registry): {job_registry.get_registered_functions()}"
|
|
517
519
|
)
|
|
518
520
|
logger.debug(f"Effective RRQ settings for worker: {rrq_settings}")
|
|
519
521
|
|
|
520
522
|
worker_instance = RRQWorker(
|
|
521
523
|
settings=rrq_settings,
|
|
522
|
-
job_registry=
|
|
524
|
+
job_registry=job_registry,
|
|
523
525
|
queues=queues_arg,
|
|
524
526
|
burst=burst,
|
|
525
527
|
)
|
|
@@ -63,7 +63,10 @@ def auto_discover_commands(package_path: str) -> list[type[BaseCommand]]:
|
|
|
63
63
|
# Get the package module
|
|
64
64
|
try:
|
|
65
65
|
package = importlib.import_module(package_path)
|
|
66
|
-
|
|
66
|
+
package_file = package.__file__
|
|
67
|
+
if package_file is None:
|
|
68
|
+
return commands
|
|
69
|
+
package_dir = os.path.dirname(package_file)
|
|
67
70
|
except ImportError:
|
|
68
71
|
# Return empty list for non-existent packages
|
|
69
72
|
return commands
|
|
@@ -452,7 +452,7 @@ class DebugCommands(AsyncCommand):
|
|
|
452
452
|
console.print(f"Delay: {delay}s")
|
|
453
453
|
|
|
454
454
|
finally:
|
|
455
|
-
await client.
|
|
455
|
+
await client.close()
|
|
456
456
|
|
|
457
457
|
async def _clear_data(
|
|
458
458
|
self, settings_object_path: str, confirm: bool, pattern: str
|
|
@@ -548,4 +548,4 @@ class DebugCommands(AsyncCommand):
|
|
|
548
548
|
console.print(f"\nStress test complete: {total_jobs} jobs submitted")
|
|
549
549
|
|
|
550
550
|
finally:
|
|
551
|
-
await client.
|
|
551
|
+
await client.close()
|