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.
Files changed (37) hide show
  1. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/PKG-INFO +33 -9
  2. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/README.md +32 -8
  3. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/cli.py +860 -738
  4. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/chain/chain.py +59 -47
  5. broccoli_workers-0.1.2/broccoli/core/chain/chain_queue.py +21 -0
  6. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/chain/task_chain.py +169 -154
  7. broccoli_workers-0.1.2/broccoli/core/redis_controller.py +66 -0
  8. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/result.py +60 -48
  9. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/task/task.py +88 -63
  10. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/task/task_queue.py +517 -510
  11. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/__init__.py +17 -15
  12. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/async_worker.py +176 -172
  13. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/base_worker.py +412 -396
  14. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/chain_worker.py +131 -119
  15. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/hybrid_worker.py +288 -284
  16. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/threaded_worker.py +166 -162
  17. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/PKG-INFO +33 -9
  18. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/pyproject.toml +1 -1
  19. broccoli_workers-0.1.1/broccoli/core/chain/chain_queue.py +0 -12
  20. broccoli_workers-0.1.1/broccoli/core/redis_controller.py +0 -39
  21. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/LICENSE +0 -0
  22. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/__init__.py +0 -0
  23. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/__init__.py +0 -0
  24. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/gpu/gpu_queue.py +0 -0
  25. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/health.py +0 -0
  26. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/core/task/task_registry.py +0 -0
  27. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/logging_config.py +0 -0
  28. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/GPUAutoScalingPool.py +0 -0
  29. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/auto_scale_worker.py +0 -0
  30. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/gpu_worker.py +0 -0
  31. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli/workers/worker_pool.py +0 -0
  32. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/SOURCES.txt +0 -0
  33. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/dependency_links.txt +0 -0
  34. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/entry_points.txt +0 -0
  35. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/requires.txt +0 -0
  36. {broccoli_workers-0.1.1 → broccoli_workers-0.1.2}/broccoli_workers.egg-info/top_level.txt +0 -0
  37. {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.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=<task_id>`
97
- - Dependent tasks are marked `waiting` until their parent completes
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(redis_url="redis://localhost:6379")
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 ID
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 parent already completed, dependent is enqueued immediately.
286
- - If parent not complete, dependent enters `waiting` and is linked under `dependency:<parent_id>`.
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 are released and enqueued using their original priority.
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=<task_id>`
49
- - Dependent tasks are marked `waiting` until their parent completes
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(redis_url="redis://localhost:6379")
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 ID
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 parent already completed, dependent is enqueued immediately.
238
- - If parent not complete, dependent enters `waiting` and is linked under `dependency:<parent_id>`.
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 are released and enqueued using their original priority.
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)`