broccoli-workers 0.1.1__tar.gz → 0.1.2__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.
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/PKG-INFO +33 -9
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/README.md +32 -8
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/cli.py +860 -738
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/chain/chain.py +59 -47
- broccoli_workers-0.1.2/broccoli/core/chain/chain_queue.py +21 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/chain/task_chain.py +169 -154
- broccoli_workers-0.1.2/broccoli/core/redis_controller.py +66 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/result.py +60 -48
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/task/task.py +88 -63
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/task/task_queue.py +517 -510
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/__init__.py +17 -15
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/async_worker.py +176 -172
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/base_worker.py +412 -396
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/chain_worker.py +131 -119
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/hybrid_worker.py +288 -284
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/threaded_worker.py +166 -162
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/PKG-INFO +33 -9
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/pyproject.toml +1 -1
- broccoli_workers-0.1.1/broccoli/core/chain/chain_queue.py +0 -12
- broccoli_workers-0.1.1/broccoli/core/redis_controller.py +0 -39
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/LICENSE +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/__init__.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/__init__.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/gpu/gpu_queue.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/health.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/task/task_registry.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/logging_config.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/GPUAutoScalingPool.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/auto_scale_worker.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/gpu_worker.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/worker_pool.py +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/SOURCES.txt +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/dependency_links.txt +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/entry_points.txt +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/requires.txt +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/top_level.txt +0 -0
- {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: broccoli-workers
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Distributed task queue with priorities, dependencies, and chains, backed by Redis
|
|
5
5
|
Author-email: Success Oguntuyi <oguntuyisuccess@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -54,7 +54,7 @@ Broccoli is a Redis-backed Python task queue for running background work with:
|
|
|
54
54
|
- **Dependency-aware tasks** (`depends_on`)
|
|
55
55
|
- **Retries + dead-letter handling**
|
|
56
56
|
- **Crash/stall recovery**
|
|
57
|
-
- **Multiple worker runtimes** (base, threaded, async, hybrid, chain)
|
|
57
|
+
- **Multiple worker runtimes** (base, threaded, async, hybrid, chain, gpu)
|
|
58
58
|
- **CLI tooling** for operational inspection and control
|
|
59
59
|
|
|
60
60
|
It is designed for teams that want Celery-like queue behavior with a smaller, explicit codebase.
|
|
@@ -93,8 +93,8 @@ It is designed for teams that want Celery-like queue behavior with a smaller, ex
|
|
|
93
93
|
|
|
94
94
|
### Dependency-aware execution
|
|
95
95
|
|
|
96
|
-
- A task can declare `depends_on
|
|
97
|
-
- Dependent tasks are marked `waiting` until
|
|
96
|
+
- A task can declare `depends_on=[<task_id>, ...]` for fan-out/fan-in style waits
|
|
97
|
+
- Dependent tasks are marked `waiting` until all listed parents complete
|
|
98
98
|
- Dependency release is handled automatically on parent completion
|
|
99
99
|
|
|
100
100
|
### Worker execution models
|
|
@@ -104,6 +104,7 @@ It is designed for teams that want Celery-like queue behavior with a smaller, ex
|
|
|
104
104
|
- Asyncio worker (`AsyncWorker`)
|
|
105
105
|
- Hybrid worker (`HybridWorker`: async dispatch + threaded execution)
|
|
106
106
|
- Chain-specific worker (`ChainWorker`)
|
|
107
|
+
- GPU worker (`GPUWorker`: hybrid worker pinned to a GPU queue/device)
|
|
107
108
|
|
|
108
109
|
### Reliability and failure handling
|
|
109
110
|
|
|
@@ -166,7 +167,10 @@ pip install -e .
|
|
|
166
167
|
from broccoli.core.task.task import Task
|
|
167
168
|
from broccoli.core.task.task_queue import TaskQueue
|
|
168
169
|
|
|
169
|
-
queue = TaskQueue(
|
|
170
|
+
queue = TaskQueue(
|
|
171
|
+
redis_url="redis://localhost:6379",
|
|
172
|
+
decode_responses=True, # set False to work with raw Redis bytes
|
|
173
|
+
)
|
|
170
174
|
|
|
171
175
|
task = Task(task_type="send_email", payload={"to": "user@example.com"})
|
|
172
176
|
queue.push(task, priority=1)
|
|
@@ -202,7 +206,7 @@ worker.start()
|
|
|
202
206
|
- `status`: `pending | waiting | in_progress | completed | failed`
|
|
203
207
|
- `retries`: current retry count
|
|
204
208
|
- `max_retries`: retry limit
|
|
205
|
-
- `depends_on`: optional parent task
|
|
209
|
+
- `depends_on`: optional list of parent task IDs
|
|
206
210
|
- `result`: handler output
|
|
207
211
|
- `error`: error message for failed attempts
|
|
208
212
|
|
|
@@ -276,16 +280,22 @@ worker.registry.register_manually("my_task", my_task_handler)
|
|
|
276
280
|
- Updates chain progress and completion state
|
|
277
281
|
- Works with `TaskChain`
|
|
278
282
|
|
|
283
|
+
### GPUWorker
|
|
284
|
+
|
|
285
|
+
- Dedicated worker for GPU workloads (`gpu_tasks:queue`)
|
|
286
|
+
- Pins execution to a selected GPU via `--gpu-id`
|
|
287
|
+
- Uses `HybridWorker` execution model with GPU cache cleanup
|
|
288
|
+
|
|
279
289
|
---
|
|
280
290
|
|
|
281
291
|
## Task dependencies
|
|
282
292
|
|
|
283
293
|
When pushing dependent tasks:
|
|
284
294
|
|
|
285
|
-
- If
|
|
286
|
-
- If
|
|
295
|
+
- If all parents already completed, dependent is enqueued immediately.
|
|
296
|
+
- If one or more parents are incomplete, dependent enters `waiting` and is linked under each unresolved `dependency:<parent_id>` set.
|
|
287
297
|
|
|
288
|
-
On parent completion, waiting tasks
|
|
298
|
+
On parent completion, waiting tasks decrement their remaining dependency count and enqueue only when all dependencies are satisfied.
|
|
289
299
|
|
|
290
300
|
Helpful APIs:
|
|
291
301
|
|
|
@@ -346,6 +356,7 @@ broccoli worker start --type threaded
|
|
|
346
356
|
broccoli worker start --type async --concurrency 20
|
|
347
357
|
broccoli worker start --type hybrid --thread-workers 8 --async-tasks 50
|
|
348
358
|
broccoli worker start --type chain --chain-queue-name chain_tasks:queue
|
|
359
|
+
broccoli worker start --type gpu --gpu-id 0
|
|
349
360
|
broccoli worker start --type threaded --pool --num-workers 4
|
|
350
361
|
```
|
|
351
362
|
|
|
@@ -359,6 +370,12 @@ Common worker flags:
|
|
|
359
370
|
- `--recover-stalled`
|
|
360
371
|
- `--recover-stalled-timeout`
|
|
361
372
|
- `--recover-on-startup` / `--no-recover-on-startup`
|
|
373
|
+
- `--decode-responses` / `--no-decode-responses`
|
|
374
|
+
- `--redis-socket-timeout`
|
|
375
|
+
- `--redis-socket-connect-timeout`
|
|
376
|
+
- `--redis-health-check-interval`
|
|
377
|
+
- `--redis-retry-on-timeout` / `--no-redis-retry-on-timeout`
|
|
378
|
+
- `--redis-max-connections`
|
|
362
379
|
|
|
363
380
|
### Queue inspection
|
|
364
381
|
|
|
@@ -401,6 +418,12 @@ Broccoli CLI defaults can come from environment variables:
|
|
|
401
418
|
- `BROCCOLI_QUEUE_NAME` (default: `tasks:queue`)
|
|
402
419
|
- `BROCCOLI_CHAIN_QUEUE_NAME` (default: `chain_tasks:queue`)
|
|
403
420
|
- `BROCCOLI_TASK_PREFIX` (default: `task`)
|
|
421
|
+
- `BROCCOLI_REDIS_DECODE_RESPONSES` (default: `true`)
|
|
422
|
+
- `BROCCOLI_REDIS_SOCKET_TIMEOUT` (optional, seconds)
|
|
423
|
+
- `BROCCOLI_REDIS_SOCKET_CONNECT_TIMEOUT` (optional, seconds)
|
|
424
|
+
- `BROCCOLI_REDIS_HEALTH_CHECK_INTERVAL` (default: `30`)
|
|
425
|
+
- `BROCCOLI_REDIS_RETRY_ON_TIMEOUT` (default: `true`)
|
|
426
|
+
- `BROCCOLI_REDIS_MAX_CONNECTIONS` (optional)
|
|
404
427
|
|
|
405
428
|
---
|
|
406
429
|
|
|
@@ -408,6 +431,7 @@ Broccoli CLI defaults can come from environment variables:
|
|
|
408
431
|
|
|
409
432
|
### TaskQueue
|
|
410
433
|
|
|
434
|
+
- constructor: `TaskQueue(redis_url=..., queue_name=..., task_prefix=..., decode_responses=True, redis_config={...})`
|
|
411
435
|
- `push(task, priority=0) -> task_id`
|
|
412
436
|
- `pop() -> Task | None`
|
|
413
437
|
- `complete(task)`
|
|
@@ -6,7 +6,7 @@ Broccoli is a Redis-backed Python task queue for running background work with:
|
|
|
6
6
|
- **Dependency-aware tasks** (`depends_on`)
|
|
7
7
|
- **Retries + dead-letter handling**
|
|
8
8
|
- **Crash/stall recovery**
|
|
9
|
-
- **Multiple worker runtimes** (base, threaded, async, hybrid, chain)
|
|
9
|
+
- **Multiple worker runtimes** (base, threaded, async, hybrid, chain, gpu)
|
|
10
10
|
- **CLI tooling** for operational inspection and control
|
|
11
11
|
|
|
12
12
|
It is designed for teams that want Celery-like queue behavior with a smaller, explicit codebase.
|
|
@@ -45,8 +45,8 @@ It is designed for teams that want Celery-like queue behavior with a smaller, ex
|
|
|
45
45
|
|
|
46
46
|
### Dependency-aware execution
|
|
47
47
|
|
|
48
|
-
- A task can declare `depends_on
|
|
49
|
-
- Dependent tasks are marked `waiting` until
|
|
48
|
+
- A task can declare `depends_on=[<task_id>, ...]` for fan-out/fan-in style waits
|
|
49
|
+
- Dependent tasks are marked `waiting` until all listed parents complete
|
|
50
50
|
- Dependency release is handled automatically on parent completion
|
|
51
51
|
|
|
52
52
|
### Worker execution models
|
|
@@ -56,6 +56,7 @@ It is designed for teams that want Celery-like queue behavior with a smaller, ex
|
|
|
56
56
|
- Asyncio worker (`AsyncWorker`)
|
|
57
57
|
- Hybrid worker (`HybridWorker`: async dispatch + threaded execution)
|
|
58
58
|
- Chain-specific worker (`ChainWorker`)
|
|
59
|
+
- GPU worker (`GPUWorker`: hybrid worker pinned to a GPU queue/device)
|
|
59
60
|
|
|
60
61
|
### Reliability and failure handling
|
|
61
62
|
|
|
@@ -118,7 +119,10 @@ pip install -e .
|
|
|
118
119
|
from broccoli.core.task.task import Task
|
|
119
120
|
from broccoli.core.task.task_queue import TaskQueue
|
|
120
121
|
|
|
121
|
-
queue = TaskQueue(
|
|
122
|
+
queue = TaskQueue(
|
|
123
|
+
redis_url="redis://localhost:6379",
|
|
124
|
+
decode_responses=True, # set False to work with raw Redis bytes
|
|
125
|
+
)
|
|
122
126
|
|
|
123
127
|
task = Task(task_type="send_email", payload={"to": "user@example.com"})
|
|
124
128
|
queue.push(task, priority=1)
|
|
@@ -154,7 +158,7 @@ worker.start()
|
|
|
154
158
|
- `status`: `pending | waiting | in_progress | completed | failed`
|
|
155
159
|
- `retries`: current retry count
|
|
156
160
|
- `max_retries`: retry limit
|
|
157
|
-
- `depends_on`: optional parent task
|
|
161
|
+
- `depends_on`: optional list of parent task IDs
|
|
158
162
|
- `result`: handler output
|
|
159
163
|
- `error`: error message for failed attempts
|
|
160
164
|
|
|
@@ -228,16 +232,22 @@ worker.registry.register_manually("my_task", my_task_handler)
|
|
|
228
232
|
- Updates chain progress and completion state
|
|
229
233
|
- Works with `TaskChain`
|
|
230
234
|
|
|
235
|
+
### GPUWorker
|
|
236
|
+
|
|
237
|
+
- Dedicated worker for GPU workloads (`gpu_tasks:queue`)
|
|
238
|
+
- Pins execution to a selected GPU via `--gpu-id`
|
|
239
|
+
- Uses `HybridWorker` execution model with GPU cache cleanup
|
|
240
|
+
|
|
231
241
|
---
|
|
232
242
|
|
|
233
243
|
## Task dependencies
|
|
234
244
|
|
|
235
245
|
When pushing dependent tasks:
|
|
236
246
|
|
|
237
|
-
- If
|
|
238
|
-
- If
|
|
247
|
+
- If all parents already completed, dependent is enqueued immediately.
|
|
248
|
+
- If one or more parents are incomplete, dependent enters `waiting` and is linked under each unresolved `dependency:<parent_id>` set.
|
|
239
249
|
|
|
240
|
-
On parent completion, waiting tasks
|
|
250
|
+
On parent completion, waiting tasks decrement their remaining dependency count and enqueue only when all dependencies are satisfied.
|
|
241
251
|
|
|
242
252
|
Helpful APIs:
|
|
243
253
|
|
|
@@ -298,6 +308,7 @@ broccoli worker start --type threaded
|
|
|
298
308
|
broccoli worker start --type async --concurrency 20
|
|
299
309
|
broccoli worker start --type hybrid --thread-workers 8 --async-tasks 50
|
|
300
310
|
broccoli worker start --type chain --chain-queue-name chain_tasks:queue
|
|
311
|
+
broccoli worker start --type gpu --gpu-id 0
|
|
301
312
|
broccoli worker start --type threaded --pool --num-workers 4
|
|
302
313
|
```
|
|
303
314
|
|
|
@@ -311,6 +322,12 @@ Common worker flags:
|
|
|
311
322
|
- `--recover-stalled`
|
|
312
323
|
- `--recover-stalled-timeout`
|
|
313
324
|
- `--recover-on-startup` / `--no-recover-on-startup`
|
|
325
|
+
- `--decode-responses` / `--no-decode-responses`
|
|
326
|
+
- `--redis-socket-timeout`
|
|
327
|
+
- `--redis-socket-connect-timeout`
|
|
328
|
+
- `--redis-health-check-interval`
|
|
329
|
+
- `--redis-retry-on-timeout` / `--no-redis-retry-on-timeout`
|
|
330
|
+
- `--redis-max-connections`
|
|
314
331
|
|
|
315
332
|
### Queue inspection
|
|
316
333
|
|
|
@@ -353,6 +370,12 @@ Broccoli CLI defaults can come from environment variables:
|
|
|
353
370
|
- `BROCCOLI_QUEUE_NAME` (default: `tasks:queue`)
|
|
354
371
|
- `BROCCOLI_CHAIN_QUEUE_NAME` (default: `chain_tasks:queue`)
|
|
355
372
|
- `BROCCOLI_TASK_PREFIX` (default: `task`)
|
|
373
|
+
- `BROCCOLI_REDIS_DECODE_RESPONSES` (default: `true`)
|
|
374
|
+
- `BROCCOLI_REDIS_SOCKET_TIMEOUT` (optional, seconds)
|
|
375
|
+
- `BROCCOLI_REDIS_SOCKET_CONNECT_TIMEOUT` (optional, seconds)
|
|
376
|
+
- `BROCCOLI_REDIS_HEALTH_CHECK_INTERVAL` (default: `30`)
|
|
377
|
+
- `BROCCOLI_REDIS_RETRY_ON_TIMEOUT` (default: `true`)
|
|
378
|
+
- `BROCCOLI_REDIS_MAX_CONNECTIONS` (optional)
|
|
356
379
|
|
|
357
380
|
---
|
|
358
381
|
|
|
@@ -360,6 +383,7 @@ Broccoli CLI defaults can come from environment variables:
|
|
|
360
383
|
|
|
361
384
|
### TaskQueue
|
|
362
385
|
|
|
386
|
+
- constructor: `TaskQueue(redis_url=..., queue_name=..., task_prefix=..., decode_responses=True, redis_config={...})`
|
|
363
387
|
- `push(task, priority=0) -> task_id`
|
|
364
388
|
- `pop() -> Task | None`
|
|
365
389
|
- `complete(task)`
|