66pip install litestar-saq
77```
88
9+ For OpenTelemetry support:
10+
11+ ``` shell
12+ pip install litestar-saq[otel]
13+ ```
14+
915## Usage
1016
1117Here is a basic application that demonstrates how to use the plugin.
1218
1319``` python
14- from __future__ import annotations
15-
1620from litestar import Litestar
17-
1821from litestar_saq import QueueConfig, SAQConfig, SAQPlugin
1922
20- saq = SAQPlugin(config = SAQConfig(dsn = " redis://localhost:6397/0" , queue_configs = [QueueConfig(name = " samples" )]))
23+ saq = SAQPlugin(
24+ config = SAQConfig(
25+ use_server_lifespan = True ,
26+ queue_configs = [
27+ QueueConfig(name = " samples" , dsn = " redis://localhost:6379/0" )
28+ ],
29+ )
30+ )
2131app = Litestar(plugins = [saq])
22-
23-
2432```
2533
2634You can start a background worker with the following command now:
@@ -29,7 +37,7 @@ You can start a background worker with the following command now:
2937litestar --app-dir=examples/ --app basic:app workers run
3038Using Litestar app from env: ' basic:app'
3139Starting SAQ Workers ──────────────────────────────────────────────────────────────────
32- INFO - 2023-10-04 17:39:03,255 - saq - worker - Worker starting: Queue< redis=Redis< ConnectionPool< Connection< host=localhost,port=6397 ,db=0>>>, name=' samples' >
40+ INFO - 2023-10-04 17:39:03,255 - saq - worker - Worker starting: Queue< redis=Redis< ConnectionPool< Connection< host=localhost,port=6379 ,db=0>>>, name=' samples' >
3341INFO - 2023-10-04 17:39:06,545 - saq - worker - Worker shutting down
3442```
3543
@@ -39,7 +47,7 @@ You can also start the process for only specific queues. This is helpful if you
3947litestar --app-dir=examples/ --app basic:app workers run --queues sample
4048Using Litestar app from env: ' basic:app'
4149Starting SAQ Workers ──────────────────────────────────────────────────────────────────
42- INFO - 2023-10-04 17:39:03,255 - saq - worker - Worker starting: Queue< redis=Redis< ConnectionPool< Connection< host=localhost,port=6397 ,db=0>>>, name=' samples' >
50+ INFO - 2023-10-04 17:39:03,255 - saq - worker - Worker starting: Queue< redis=Redis< ConnectionPool< Connection< host=localhost,port=6379 ,db=0>>>, name=' samples' >
4351INFO - 2023-10-04 17:39:06,545 - saq - worker - Worker shutting down
4452```
4553
@@ -49,16 +57,59 @@ If you are starting the process for only specific queues and still want to read
4957import os
5058from saq import Queue
5159
52-
5360def get_queue_directly (queue_name : str , redis_url : str ) -> Queue:
5461 return Queue.from_url(redis_url, name = queue_name)
5562
5663redis_url = os.getenv(" REDIS_URL" )
5764queue = get_queue_directly(" queue-in-other-process" , redis_url)
65+
5866# Get queue info
5967info = await queue.info(jobs = True )
68+
6069# Enqueue new task
61- queue.enqueue(
62- ... .
70+ await queue.enqueue(" task_name" , arg1 = " value1" )
71+ ```
72+
73+ ## Monitored Jobs
74+
75+ For long-running tasks, use the ` monitored_job ` decorator to automatically send heartbeats and prevent SAQ from marking jobs as stuck:
76+
77+ ``` python
78+ from litestar_saq import monitored_job
79+
80+ @monitored_job () # Auto-calculates interval from job.heartbeat
81+ async def long_running_task (ctx ):
82+ await process_large_dataset()
83+ return {" status" : " complete" }
84+
85+ @monitored_job (interval = 30.0 ) # Explicit 30-second interval
86+ async def train_model (ctx , model_id : str ):
87+ for epoch in range (100 ):
88+ await train_epoch(model)
89+ return {" model_id" : model_id}
90+ ```
91+
92+ ## OpenTelemetry Integration
93+
94+ litestar-saq supports optional OpenTelemetry instrumentation for distributed tracing.
95+
96+ ### Configuration
97+
98+ ``` python
99+ from litestar_saq import SAQConfig, QueueConfig
100+
101+ config = SAQConfig(
102+ queue_configs = [QueueConfig(dsn = " redis://localhost:6379/0" )],
103+ enable_otel = None , # Auto-detect (default) - enabled if OTEL installed AND Litestar OpenTelemetryPlugin is active
104+ # enable_otel=True, # Force enable (raises error if not installed)
105+ # enable_otel=False, # Force disable
63106)
64107```
108+
109+ When enabled, the plugin creates:
110+
111+ - ** CONSUMER spans** for job processing
112+ - ** PRODUCER spans** for job enqueue operations
113+ - ** Automatic context propagation** across process boundaries
114+
115+ Spans follow [ OpenTelemetry messaging semantic conventions] ( https://opentelemetry.io/docs/specs/semconv/messaging/ ) with ` messaging.system = "saq" ` .
0 commit comments