jararaca 0.3.11a7__tar.gz → 0.3.11a8__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.
Potentially problematic release.
This version of jararaca might be problematic. Click here for more details.
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/PKG-INFO +1 -1
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/pyproject.toml +1 -1
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/cli.py +190 -15
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/decorators.py +2 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/worker.py +28 -10
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/worker_v2.py +23 -1
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/scheduler/decorators.py +7 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/scheduler/scheduler.py +17 -2
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/scheduler/scheduler_v2.py +22 -5
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/utils/rabbitmq_utils.py +78 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/LICENSE +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/README.md +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/CNAME +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/architecture.md +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.webp +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/assets/tracing_example.png +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/index.md +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/messagebus.md +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/scheduler.md +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/stylesheets/custom.css +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/websocket.md +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/__main__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/broker_backend/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/broker_backend/mapper.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/broker_backend/redis_broker_backend.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/common/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/core/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/core/providers.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/core/uow.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/di.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/files/entity.py.mako +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/lifecycle.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/bus_message_controller.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/consumers/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/interceptors/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/interceptors/publisher_interceptor.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/message.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/messagebus/publisher.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/microservice.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/observability/decorators.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/observability/interceptor.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/observability/providers/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/observability/providers/otel.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/persistence/base.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/persistence/exports.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/persistence/interceptors/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/persistence/interceptors/aiosqa_interceptor.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/persistence/session.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/persistence/sort_filter.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/persistence/utilities.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/decorators.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/hooks.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/http_microservice.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/server.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/websocket/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/websocket/base_types.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/websocket/context.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/websocket/decorators.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/websocket/redis.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/websocket/types.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/websocket/websocket_interceptor.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/py.typed +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/reflect/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/reflect/controller_inspect.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/reflect/metadata.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/rpc/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/rpc/http/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/rpc/http/backends/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/rpc/http/backends/httpx.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/rpc/http/backends/otel.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/rpc/http/decorators.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/rpc/http/httpx.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/scheduler/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/scheduler/types.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/tools/app_config/__init__.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/tools/app_config/decorators.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/tools/app_config/interceptor.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/tools/typescript/interface_parser.py +0 -0
- {jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/utils/__init__.py +0 -0
|
@@ -17,6 +17,7 @@ from mako.template import Template
|
|
|
17
17
|
|
|
18
18
|
from jararaca.messagebus import worker as worker_v1
|
|
19
19
|
from jararaca.messagebus import worker_v2 as worker_v2_mod
|
|
20
|
+
from jararaca.messagebus.decorators import SCHEDULED_ACTION_DATA_SET
|
|
20
21
|
from jararaca.microservice import Microservice
|
|
21
22
|
from jararaca.presentation.http_microservice import HttpMicroservice
|
|
22
23
|
from jararaca.presentation.server import create_http_server
|
|
@@ -75,6 +76,8 @@ async def declare_worker_infrastructure(
|
|
|
75
76
|
exchange: str,
|
|
76
77
|
app: Microservice,
|
|
77
78
|
passive_declare: bool = False,
|
|
79
|
+
handler_names: set[str] | None = None,
|
|
80
|
+
force: bool = False,
|
|
78
81
|
) -> None:
|
|
79
82
|
"""
|
|
80
83
|
Declare the infrastructure (exchanges and queues) for worker v1.
|
|
@@ -82,6 +85,13 @@ async def declare_worker_infrastructure(
|
|
|
82
85
|
connection = await aio_pika.connect(url)
|
|
83
86
|
channel = await connection.channel()
|
|
84
87
|
|
|
88
|
+
# Force delete infrastructure if requested
|
|
89
|
+
if force:
|
|
90
|
+
click.echo(f"→ Force deleting existing infrastructure for exchange: {exchange}")
|
|
91
|
+
await RabbitmqUtils.delete_exchange(channel, exchange)
|
|
92
|
+
await RabbitmqUtils.delete_exchange(channel, RabbitmqUtils.DEAD_LETTER_EXCHANGE)
|
|
93
|
+
await RabbitmqUtils.delete_queue(channel, RabbitmqUtils.DEAD_LETTER_QUEUE)
|
|
94
|
+
|
|
85
95
|
# Declare main exchange
|
|
86
96
|
main_ex = await RabbitmqUtils.declare_main_exchange(
|
|
87
97
|
channel=channel,
|
|
@@ -110,17 +120,27 @@ async def declare_worker_infrastructure(
|
|
|
110
120
|
handlers, _ = factory(instance)
|
|
111
121
|
|
|
112
122
|
for handler in handlers:
|
|
123
|
+
# Filter handlers by name if specified
|
|
124
|
+
if handler_names is not None and handler.spec.name is not None:
|
|
125
|
+
if handler.spec.name not in handler_names:
|
|
126
|
+
continue
|
|
127
|
+
elif handler_names is not None and handler.spec.name is None:
|
|
128
|
+
# Skip handlers without names when filtering is requested
|
|
129
|
+
continue
|
|
130
|
+
|
|
113
131
|
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.instance_callable.__module__}.{handler.instance_callable.__qualname__}"
|
|
114
132
|
routing_key = f"{handler.message_type.MESSAGE_TOPIC}.#"
|
|
115
133
|
|
|
116
|
-
queue
|
|
134
|
+
# Force delete queue if requested
|
|
135
|
+
if force:
|
|
136
|
+
await RabbitmqUtils.delete_queue(channel, queue_name)
|
|
137
|
+
|
|
138
|
+
queue = await RabbitmqUtils.declare_worker_v1_queue(
|
|
139
|
+
channel=channel,
|
|
140
|
+
queue_name=queue_name,
|
|
141
|
+
dlx_name=dlx.name,
|
|
142
|
+
dlq_name=dlq.name,
|
|
117
143
|
passive=passive_declare,
|
|
118
|
-
name=queue_name,
|
|
119
|
-
arguments={
|
|
120
|
-
"x-dead-letter-exchange": dlx.name,
|
|
121
|
-
"x-dead-letter-routing-key": dlq.name,
|
|
122
|
-
},
|
|
123
|
-
durable=True,
|
|
124
144
|
)
|
|
125
145
|
|
|
126
146
|
await queue.bind(exchange=main_ex, routing_key=routing_key)
|
|
@@ -134,6 +154,8 @@ async def declare_worker_v2_infrastructure(
|
|
|
134
154
|
broker_url: str,
|
|
135
155
|
app: Microservice,
|
|
136
156
|
passive_declare: bool = False,
|
|
157
|
+
handler_names: set[str] | None = None,
|
|
158
|
+
force: bool = False,
|
|
137
159
|
) -> None:
|
|
138
160
|
"""
|
|
139
161
|
Declare the infrastructure (exchanges and queues) for worker v2.
|
|
@@ -157,6 +179,13 @@ async def declare_worker_v2_infrastructure(
|
|
|
157
179
|
connection = await aio_pika.connect(broker_url)
|
|
158
180
|
channel = await connection.channel()
|
|
159
181
|
|
|
182
|
+
# Force delete infrastructure if requested
|
|
183
|
+
if force:
|
|
184
|
+
click.echo(f"→ Force deleting existing infrastructure for exchange: {exchange}")
|
|
185
|
+
await RabbitmqUtils.delete_exchange(channel, exchange)
|
|
186
|
+
await RabbitmqUtils.delete_exchange(channel, RabbitmqUtils.DEAD_LETTER_EXCHANGE)
|
|
187
|
+
await RabbitmqUtils.delete_queue(channel, RabbitmqUtils.DEAD_LETTER_QUEUE)
|
|
188
|
+
|
|
160
189
|
# Declare main exchange
|
|
161
190
|
await RabbitmqUtils.declare_main_exchange(
|
|
162
191
|
channel=channel,
|
|
@@ -188,9 +217,21 @@ async def declare_worker_v2_infrastructure(
|
|
|
188
217
|
|
|
189
218
|
# Declare queues for message handlers
|
|
190
219
|
for handler in handlers:
|
|
220
|
+
# Filter handlers by name if specified
|
|
221
|
+
if handler_names is not None and handler.spec.name is not None:
|
|
222
|
+
if handler.spec.name not in handler_names:
|
|
223
|
+
continue
|
|
224
|
+
elif handler_names is not None and handler.spec.name is None:
|
|
225
|
+
# Skip handlers without names when filtering is requested
|
|
226
|
+
continue
|
|
227
|
+
|
|
191
228
|
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.instance_callable.__module__}.{handler.instance_callable.__qualname__}"
|
|
192
229
|
routing_key = f"{handler.message_type.MESSAGE_TOPIC}.#"
|
|
193
230
|
|
|
231
|
+
# Force delete queue if requested
|
|
232
|
+
if force:
|
|
233
|
+
await RabbitmqUtils.delete_queue(channel, queue_name)
|
|
234
|
+
|
|
194
235
|
queue = await RabbitmqUtils.declare_queue(
|
|
195
236
|
channel=channel, queue_name=queue_name, passive=passive_declare
|
|
196
237
|
)
|
|
@@ -204,6 +245,10 @@ async def declare_worker_v2_infrastructure(
|
|
|
204
245
|
queue_name = f"{scheduled_action.callable.__module__}.{scheduled_action.callable.__qualname__}"
|
|
205
246
|
routing_key = queue_name
|
|
206
247
|
|
|
248
|
+
# Force delete queue if requested
|
|
249
|
+
if force:
|
|
250
|
+
await RabbitmqUtils.delete_queue(channel, queue_name)
|
|
251
|
+
|
|
207
252
|
queue = await RabbitmqUtils.declare_queue(
|
|
208
253
|
channel=channel, queue_name=queue_name, passive=passive_declare
|
|
209
254
|
)
|
|
@@ -220,6 +265,8 @@ async def declare_scheduler_v2_infrastructure(
|
|
|
220
265
|
broker_url: str,
|
|
221
266
|
app: Microservice,
|
|
222
267
|
passive_declare: bool = False,
|
|
268
|
+
scheduler_names: set[str] | None = None,
|
|
269
|
+
force: bool = False,
|
|
223
270
|
) -> None:
|
|
224
271
|
"""
|
|
225
272
|
Declare the infrastructure (exchanges and queues) for scheduler v2.
|
|
@@ -245,6 +292,10 @@ async def declare_scheduler_v2_infrastructure(
|
|
|
245
292
|
connection = await aio_pika.connect(broker_url)
|
|
246
293
|
channel = await connection.channel()
|
|
247
294
|
|
|
295
|
+
# Force delete exchange if requested
|
|
296
|
+
if force:
|
|
297
|
+
await RabbitmqUtils.delete_exchange(channel, exchange)
|
|
298
|
+
|
|
248
299
|
# Declare exchange for scheduler
|
|
249
300
|
await channel.declare_exchange(
|
|
250
301
|
name=exchange,
|
|
@@ -269,13 +320,29 @@ async def declare_scheduler_v2_infrastructure(
|
|
|
269
320
|
instance: Any = container.get_by_type(instance_type)
|
|
270
321
|
factory = controller.get_messagebus_factory()
|
|
271
322
|
_, actions = factory(instance)
|
|
323
|
+
|
|
324
|
+
# Filter scheduled actions by name if specified
|
|
325
|
+
if scheduler_names is not None:
|
|
326
|
+
filtered_actions: SCHEDULED_ACTION_DATA_SET = set()
|
|
327
|
+
for action in actions:
|
|
328
|
+
# Include actions that have a name and it's in the provided set
|
|
329
|
+
if action.spec.name and action.spec.name in scheduler_names:
|
|
330
|
+
filtered_actions.add(action)
|
|
331
|
+
# Skip actions without names when filtering is active
|
|
332
|
+
actions = filtered_actions
|
|
333
|
+
|
|
272
334
|
scheduled_actions.extend(actions)
|
|
273
335
|
|
|
274
336
|
for scheduled_action in scheduled_actions:
|
|
275
337
|
queue_name = ScheduledAction.get_function_id(scheduled_action.callable)
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
338
|
+
|
|
339
|
+
# Force delete queue if requested
|
|
340
|
+
if force:
|
|
341
|
+
await RabbitmqUtils.delete_queue(channel, queue_name)
|
|
342
|
+
|
|
343
|
+
queue = await RabbitmqUtils.declare_scheduler_queue(
|
|
344
|
+
channel=channel,
|
|
345
|
+
queue_name=queue_name,
|
|
279
346
|
passive=passive_declare,
|
|
280
347
|
)
|
|
281
348
|
await queue.bind(
|
|
@@ -328,6 +395,11 @@ def cli() -> None:
|
|
|
328
395
|
is_flag=True,
|
|
329
396
|
default=False,
|
|
330
397
|
)
|
|
398
|
+
@click.option(
|
|
399
|
+
"--handlers",
|
|
400
|
+
type=str,
|
|
401
|
+
help="Comma-separated list of handler names to listen to. If not specified, all handlers will be used.",
|
|
402
|
+
)
|
|
331
403
|
def worker(
|
|
332
404
|
app_path: str,
|
|
333
405
|
url: str,
|
|
@@ -336,6 +408,7 @@ def worker(
|
|
|
336
408
|
exchange: str,
|
|
337
409
|
prefetch_count: int,
|
|
338
410
|
passive_declare: bool,
|
|
411
|
+
handlers: str | None,
|
|
339
412
|
) -> None:
|
|
340
413
|
|
|
341
414
|
app = find_microservice_by_module_path(app_path)
|
|
@@ -362,6 +435,11 @@ def worker(
|
|
|
362
435
|
|
|
363
436
|
url = parsed_url.geturl()
|
|
364
437
|
|
|
438
|
+
# Parse handler names if provided
|
|
439
|
+
handler_names: set[str] | None = None
|
|
440
|
+
if handlers:
|
|
441
|
+
handler_names = {name.strip() for name in handlers.split(",") if name.strip()}
|
|
442
|
+
|
|
365
443
|
config = worker_v1.AioPikaWorkerConfig(
|
|
366
444
|
url=url,
|
|
367
445
|
exchange=exchange,
|
|
@@ -370,6 +448,7 @@ def worker(
|
|
|
370
448
|
|
|
371
449
|
worker_v1.MessageBusWorker(app, config=config).start_sync(
|
|
372
450
|
passive_declare=passive_declare,
|
|
451
|
+
handler_names=handler_names,
|
|
373
452
|
)
|
|
374
453
|
|
|
375
454
|
|
|
@@ -389,14 +468,27 @@ def worker(
|
|
|
389
468
|
type=str,
|
|
390
469
|
envvar="BACKEND_URL",
|
|
391
470
|
)
|
|
392
|
-
|
|
471
|
+
@click.option(
|
|
472
|
+
"--handlers",
|
|
473
|
+
type=str,
|
|
474
|
+
help="Comma-separated list of handler names to listen to. If not specified, all handlers will be used.",
|
|
475
|
+
)
|
|
476
|
+
def worker_v2(
|
|
477
|
+
app_path: str, broker_url: str, backend_url: str, handlers: str | None
|
|
478
|
+
) -> None:
|
|
393
479
|
|
|
394
480
|
app = find_microservice_by_module_path(app_path)
|
|
395
481
|
|
|
482
|
+
# Parse handler names if provided
|
|
483
|
+
handler_names: set[str] | None = None
|
|
484
|
+
if handlers:
|
|
485
|
+
handler_names = {name.strip() for name in handlers.split(",") if name.strip()}
|
|
486
|
+
|
|
396
487
|
worker_v2_mod.MessageBusWorker(
|
|
397
488
|
app=app,
|
|
398
489
|
broker_url=broker_url,
|
|
399
490
|
backend_url=backend_url,
|
|
491
|
+
handler_names=handler_names,
|
|
400
492
|
).start_sync()
|
|
401
493
|
|
|
402
494
|
|
|
@@ -449,13 +541,26 @@ def server(app_path: str, host: str, port: int) -> None:
|
|
|
449
541
|
type=int,
|
|
450
542
|
default=1,
|
|
451
543
|
)
|
|
544
|
+
@click.option(
|
|
545
|
+
"--schedulers",
|
|
546
|
+
type=str,
|
|
547
|
+
help="Comma-separated list of scheduler names to run (only run schedulers with these names)",
|
|
548
|
+
)
|
|
452
549
|
def scheduler(
|
|
453
550
|
app_path: str,
|
|
454
551
|
interval: int,
|
|
552
|
+
schedulers: str | None = None,
|
|
455
553
|
) -> None:
|
|
456
554
|
app = find_microservice_by_module_path(app_path)
|
|
457
555
|
|
|
458
|
-
|
|
556
|
+
# Parse scheduler names if provided
|
|
557
|
+
scheduler_names: set[str] | None = None
|
|
558
|
+
if schedulers:
|
|
559
|
+
scheduler_names = {
|
|
560
|
+
name.strip() for name in schedulers.split(",") if name.strip()
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
Scheduler(app, interval=interval, scheduler_names=scheduler_names).run()
|
|
459
564
|
|
|
460
565
|
|
|
461
566
|
@cli.command()
|
|
@@ -479,19 +584,34 @@ def scheduler(
|
|
|
479
584
|
type=str,
|
|
480
585
|
required=True,
|
|
481
586
|
)
|
|
587
|
+
@click.option(
|
|
588
|
+
"--schedulers",
|
|
589
|
+
type=str,
|
|
590
|
+
help="Comma-separated list of scheduler names to run (only run schedulers with these names)",
|
|
591
|
+
)
|
|
482
592
|
def scheduler_v2(
|
|
483
593
|
interval: int,
|
|
484
594
|
broker_url: str,
|
|
485
595
|
backend_url: str,
|
|
486
596
|
app_path: str,
|
|
597
|
+
schedulers: str | None = None,
|
|
487
598
|
) -> None:
|
|
488
599
|
|
|
489
600
|
app = find_microservice_by_module_path(app_path)
|
|
601
|
+
|
|
602
|
+
# Parse scheduler names if provided
|
|
603
|
+
scheduler_names: set[str] | None = None
|
|
604
|
+
if schedulers:
|
|
605
|
+
scheduler_names = {
|
|
606
|
+
name.strip() for name in schedulers.split(",") if name.strip()
|
|
607
|
+
}
|
|
608
|
+
|
|
490
609
|
scheduler = SchedulerV2(
|
|
491
610
|
app=app,
|
|
492
611
|
interval=interval,
|
|
493
612
|
backend_url=backend_url,
|
|
494
613
|
broker_url=broker_url,
|
|
614
|
+
scheduler_names=scheduler_names,
|
|
495
615
|
)
|
|
496
616
|
scheduler.run()
|
|
497
617
|
|
|
@@ -740,11 +860,24 @@ def gen_entity(entity_name: str, file_path: StreamWriter) -> None:
|
|
|
740
860
|
default=False,
|
|
741
861
|
help="Use passive declarations (check if infrastructure exists without creating it)",
|
|
742
862
|
)
|
|
863
|
+
@click.option(
|
|
864
|
+
"--handlers",
|
|
865
|
+
type=str,
|
|
866
|
+
help="Comma-separated list of handler names to declare queues for. If not specified, all handlers will be declared.",
|
|
867
|
+
)
|
|
868
|
+
@click.option(
|
|
869
|
+
"--force",
|
|
870
|
+
is_flag=True,
|
|
871
|
+
default=False,
|
|
872
|
+
help="Force recreation by deleting existing exchanges and queues before declaring them",
|
|
873
|
+
)
|
|
743
874
|
def declare_queues_v1(
|
|
744
875
|
app_path: str,
|
|
745
876
|
broker_url: str | None,
|
|
746
877
|
exchange: str,
|
|
747
878
|
passive_declare: bool,
|
|
879
|
+
handlers: str | None,
|
|
880
|
+
force: bool,
|
|
748
881
|
) -> None:
|
|
749
882
|
"""
|
|
750
883
|
Declare RabbitMQ infrastructure (exchanges and queues) for worker v1.
|
|
@@ -779,13 +912,20 @@ def declare_queues_v1(
|
|
|
779
912
|
)
|
|
780
913
|
return
|
|
781
914
|
|
|
915
|
+
# Parse handler names if provided
|
|
916
|
+
handler_names: set[str] | None = None
|
|
917
|
+
if handlers:
|
|
918
|
+
handler_names = {
|
|
919
|
+
name.strip() for name in handlers.split(",") if name.strip()
|
|
920
|
+
}
|
|
921
|
+
|
|
782
922
|
click.echo(
|
|
783
923
|
f"→ Declaring worker v1 infrastructure (URL: {broker_url}, Exchange: {exchange})"
|
|
784
924
|
)
|
|
785
925
|
|
|
786
926
|
try:
|
|
787
927
|
await declare_worker_infrastructure(
|
|
788
|
-
broker_url, exchange, app, passive_declare
|
|
928
|
+
broker_url, exchange, app, passive_declare, handler_names, force
|
|
789
929
|
)
|
|
790
930
|
click.echo("✓ Worker v1 infrastructure declared successfully!")
|
|
791
931
|
except Exception as e:
|
|
@@ -821,11 +961,30 @@ def declare_queues_v1(
|
|
|
821
961
|
default=False,
|
|
822
962
|
help="Use passive declarations (check if infrastructure exists without creating it)",
|
|
823
963
|
)
|
|
964
|
+
@click.option(
|
|
965
|
+
"--handlers",
|
|
966
|
+
type=str,
|
|
967
|
+
help="Comma-separated list of handler names to declare queues for. If not specified, all handlers will be declared.",
|
|
968
|
+
)
|
|
969
|
+
@click.option(
|
|
970
|
+
"--schedulers",
|
|
971
|
+
type=str,
|
|
972
|
+
help="Comma-separated list of scheduler names to declare queues for. If not specified, all schedulers will be declared.",
|
|
973
|
+
)
|
|
974
|
+
@click.option(
|
|
975
|
+
"--force",
|
|
976
|
+
is_flag=True,
|
|
977
|
+
default=False,
|
|
978
|
+
help="Force recreation by deleting existing exchanges and queues before declaring them",
|
|
979
|
+
)
|
|
824
980
|
def declare_queues_v2(
|
|
825
981
|
app_path: str,
|
|
826
982
|
broker_url: str | None,
|
|
827
983
|
exchange: str,
|
|
828
984
|
passive_declare: bool,
|
|
985
|
+
handlers: str | None,
|
|
986
|
+
schedulers: str | None,
|
|
987
|
+
force: bool,
|
|
829
988
|
) -> None:
|
|
830
989
|
"""
|
|
831
990
|
Declare RabbitMQ infrastructure (exchanges and queues) for worker v2 and scheduler v2.
|
|
@@ -860,6 +1019,20 @@ def declare_queues_v2(
|
|
|
860
1019
|
)
|
|
861
1020
|
return
|
|
862
1021
|
|
|
1022
|
+
# Parse handler names if provided
|
|
1023
|
+
handler_names: set[str] | None = None
|
|
1024
|
+
if handlers:
|
|
1025
|
+
handler_names = {
|
|
1026
|
+
name.strip() for name in handlers.split(",") if name.strip()
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
# Parse scheduler names if provided
|
|
1030
|
+
scheduler_names: set[str] | None = None
|
|
1031
|
+
if schedulers:
|
|
1032
|
+
scheduler_names = {
|
|
1033
|
+
name.strip() for name in schedulers.split(",") if name.strip()
|
|
1034
|
+
}
|
|
1035
|
+
|
|
863
1036
|
# For v2, create the broker URL with exchange parameter
|
|
864
1037
|
v2_broker_url = f"{broker_url}?exchange={exchange}"
|
|
865
1038
|
|
|
@@ -868,9 +1041,11 @@ def declare_queues_v2(
|
|
|
868
1041
|
|
|
869
1042
|
try:
|
|
870
1043
|
await asyncio.gather(
|
|
871
|
-
declare_worker_v2_infrastructure(
|
|
1044
|
+
declare_worker_v2_infrastructure(
|
|
1045
|
+
v2_broker_url, app, passive_declare, handler_names, force
|
|
1046
|
+
),
|
|
872
1047
|
declare_scheduler_v2_infrastructure(
|
|
873
|
-
v2_broker_url, app, passive_declare
|
|
1048
|
+
v2_broker_url, app, passive_declare, scheduler_names, force
|
|
874
1049
|
),
|
|
875
1050
|
)
|
|
876
1051
|
click.echo(
|
|
@@ -24,6 +24,7 @@ class MessageHandler(Generic[INHERITS_MESSAGE_CO]):
|
|
|
24
24
|
exception_handler: Callable[[BaseException], None] | None = None,
|
|
25
25
|
nack_on_exception: bool = False,
|
|
26
26
|
auto_ack: bool = True,
|
|
27
|
+
name: str | None = None,
|
|
27
28
|
) -> None:
|
|
28
29
|
self.message_type = message
|
|
29
30
|
|
|
@@ -31,6 +32,7 @@ class MessageHandler(Generic[INHERITS_MESSAGE_CO]):
|
|
|
31
32
|
self.exception_handler = exception_handler
|
|
32
33
|
self.requeue_on_exception = nack_on_exception
|
|
33
34
|
self.auto_ack = auto_ack
|
|
35
|
+
self.name = name
|
|
34
36
|
|
|
35
37
|
def __call__(
|
|
36
38
|
self, func: Callable[[Any, MessageOf[INHERITS_MESSAGE_CO]], Awaitable[None]]
|
|
@@ -118,13 +118,14 @@ class AioPikaMicroserviceConsumer:
|
|
|
118
118
|
|
|
119
119
|
self.incoming_map[queue_name] = handler
|
|
120
120
|
|
|
121
|
-
queue: aio_pika.abc.AbstractQueue =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
queue: aio_pika.abc.AbstractQueue = (
|
|
122
|
+
await RabbitmqUtils.declare_worker_v1_queue(
|
|
123
|
+
channel=channel,
|
|
124
|
+
queue_name=queue_name,
|
|
125
|
+
dlx_name=dlx.name,
|
|
126
|
+
dlq_name=dlq.name,
|
|
127
|
+
passive=passive_declare,
|
|
128
|
+
)
|
|
128
129
|
)
|
|
129
130
|
|
|
130
131
|
await queue.bind(exchange=main_ex, routing_key=routing_key)
|
|
@@ -337,7 +338,9 @@ class MessageBusWorker:
|
|
|
337
338
|
raise RuntimeError("Consumer not started")
|
|
338
339
|
return self._consumer
|
|
339
340
|
|
|
340
|
-
async def start_async(
|
|
341
|
+
async def start_async(
|
|
342
|
+
self, passive_declare: bool, handler_names: set[str] | None = None
|
|
343
|
+
) -> None:
|
|
341
344
|
all_message_handlers_set: MESSAGE_HANDLER_DATA_SET = set()
|
|
342
345
|
async with self.lifecycle():
|
|
343
346
|
for instance_type in self.app.controllers:
|
|
@@ -356,6 +359,15 @@ class MessageBusWorker:
|
|
|
356
359
|
for handler_data in handlers:
|
|
357
360
|
message_type = handler_data.spec.message_type
|
|
358
361
|
topic = message_type.MESSAGE_TOPIC
|
|
362
|
+
|
|
363
|
+
# Filter handlers by name if specified
|
|
364
|
+
if handler_names is not None and handler_data.spec.name is not None:
|
|
365
|
+
if handler_data.spec.name not in handler_names:
|
|
366
|
+
continue
|
|
367
|
+
elif handler_names is not None and handler_data.spec.name is None:
|
|
368
|
+
# Skip handlers without names when filtering is requested
|
|
369
|
+
continue
|
|
370
|
+
|
|
359
371
|
if (
|
|
360
372
|
topic in message_handler_data_map
|
|
361
373
|
and message_type.MESSAGE_TYPE == "task"
|
|
@@ -376,7 +388,9 @@ class MessageBusWorker:
|
|
|
376
388
|
|
|
377
389
|
await consumer.consume(passive_declare=passive_declare)
|
|
378
390
|
|
|
379
|
-
def start_sync(
|
|
391
|
+
def start_sync(
|
|
392
|
+
self, passive_declare: bool, handler_names: set[str] | None = None
|
|
393
|
+
) -> None:
|
|
380
394
|
|
|
381
395
|
def on_shutdown(loop: asyncio.AbstractEventLoop) -> None:
|
|
382
396
|
logger.info("Shutting down")
|
|
@@ -386,7 +400,11 @@ class MessageBusWorker:
|
|
|
386
400
|
runner.get_loop().add_signal_handler(
|
|
387
401
|
signal.SIGINT, on_shutdown, runner.get_loop()
|
|
388
402
|
)
|
|
389
|
-
runner.run(
|
|
403
|
+
runner.run(
|
|
404
|
+
self.start_async(
|
|
405
|
+
passive_declare=passive_declare, handler_names=handler_names
|
|
406
|
+
)
|
|
407
|
+
)
|
|
390
408
|
|
|
391
409
|
|
|
392
410
|
class AioPikaMessageBusController(BusMessageController):
|
|
@@ -515,10 +515,17 @@ async def none_context() -> AsyncGenerator[None, None]:
|
|
|
515
515
|
|
|
516
516
|
|
|
517
517
|
class MessageBusWorker:
|
|
518
|
-
def __init__(
|
|
518
|
+
def __init__(
|
|
519
|
+
self,
|
|
520
|
+
app: Microservice,
|
|
521
|
+
broker_url: str,
|
|
522
|
+
backend_url: str,
|
|
523
|
+
handler_names: set[str] | None = None,
|
|
524
|
+
) -> None:
|
|
519
525
|
self.app = app
|
|
520
526
|
self.backend_url = backend_url
|
|
521
527
|
self.broker_url = broker_url
|
|
528
|
+
self.handler_names = handler_names
|
|
522
529
|
|
|
523
530
|
self.container = Container(app)
|
|
524
531
|
self.lifecycle = AppLifecycle(app, self.container)
|
|
@@ -555,6 +562,21 @@ class MessageBusWorker:
|
|
|
555
562
|
for handler_data in handlers:
|
|
556
563
|
message_type = handler_data.spec.message_type
|
|
557
564
|
topic = message_type.MESSAGE_TOPIC
|
|
565
|
+
|
|
566
|
+
# Filter handlers by name if specified
|
|
567
|
+
if (
|
|
568
|
+
self.handler_names is not None
|
|
569
|
+
and handler_data.spec.name is not None
|
|
570
|
+
):
|
|
571
|
+
if handler_data.spec.name not in self.handler_names:
|
|
572
|
+
continue
|
|
573
|
+
elif (
|
|
574
|
+
self.handler_names is not None
|
|
575
|
+
and handler_data.spec.name is None
|
|
576
|
+
):
|
|
577
|
+
# Skip handlers without names when filtering is requested
|
|
578
|
+
continue
|
|
579
|
+
|
|
558
580
|
if (
|
|
559
581
|
topic in message_handler_data_map
|
|
560
582
|
and message_type.MESSAGE_TYPE == "task"
|
|
@@ -20,6 +20,7 @@ class ScheduledAction:
|
|
|
20
20
|
exclusive: bool = True,
|
|
21
21
|
timeout: int | None = None,
|
|
22
22
|
exception_handler: Callable[[BaseException], None] | None = None,
|
|
23
|
+
name: str | None = None,
|
|
23
24
|
) -> None:
|
|
24
25
|
"""
|
|
25
26
|
:param cron: A string representing the cron expression for the scheduled action.
|
|
@@ -27,6 +28,7 @@ class ScheduledAction:
|
|
|
27
28
|
:param exclusive: A boolean indicating if the scheduled action should be executed in one instance of the application. (Requires a distributed lock provided by a backend)
|
|
28
29
|
:param exception_handler: A callable that will be called when an exception is raised during the execution of the scheduled action.
|
|
29
30
|
:param timeout: An integer representing the timeout for the scheduled action in seconds. If the scheduled action takes longer than this time, it will be terminated.
|
|
31
|
+
:param name: An optional name for the scheduled action, used for filtering which actions to run.
|
|
30
32
|
"""
|
|
31
33
|
self.cron = cron
|
|
32
34
|
"""
|
|
@@ -55,6 +57,11 @@ class ScheduledAction:
|
|
|
55
57
|
If the scheduled action takes longer than this time, it will be terminated.
|
|
56
58
|
"""
|
|
57
59
|
|
|
60
|
+
self.name = name
|
|
61
|
+
"""
|
|
62
|
+
An optional name for the scheduled action, used for filtering which actions to run.
|
|
63
|
+
"""
|
|
64
|
+
|
|
58
65
|
def __call__(self, func: DECORATED_FUNC) -> DECORATED_FUNC:
|
|
59
66
|
ScheduledAction.register(func, self)
|
|
60
67
|
return func
|
|
@@ -34,7 +34,7 @@ class SchedulerConfig:
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def extract_scheduled_actions(
|
|
37
|
-
app: Microservice, container: Container
|
|
37
|
+
app: Microservice, container: Container, scheduler_names: set[str] | None = None
|
|
38
38
|
) -> list[ScheduledActionData]:
|
|
39
39
|
scheduled_actions: list[ScheduledActionData] = []
|
|
40
40
|
for controllers in app.controllers:
|
|
@@ -42,6 +42,17 @@ def extract_scheduled_actions(
|
|
|
42
42
|
controller_instance: Any = container.get_by_type(controllers)
|
|
43
43
|
|
|
44
44
|
controller_scheduled_actions = get_type_scheduled_actions(controller_instance)
|
|
45
|
+
|
|
46
|
+
# Filter scheduled actions by name if scheduler_names is provided
|
|
47
|
+
if scheduler_names is not None:
|
|
48
|
+
filtered_actions = []
|
|
49
|
+
for action in controller_scheduled_actions:
|
|
50
|
+
# Include actions that have a name and it's in the provided set
|
|
51
|
+
if action.spec.name and action.spec.name in scheduler_names:
|
|
52
|
+
filtered_actions.append(action)
|
|
53
|
+
# Skip actions without names when filtering is active
|
|
54
|
+
controller_scheduled_actions = filtered_actions
|
|
55
|
+
|
|
45
56
|
scheduled_actions.extend(controller_scheduled_actions)
|
|
46
57
|
|
|
47
58
|
return scheduled_actions
|
|
@@ -59,10 +70,12 @@ class Scheduler:
|
|
|
59
70
|
self,
|
|
60
71
|
app: Microservice,
|
|
61
72
|
interval: int,
|
|
73
|
+
scheduler_names: set[str] | None = None,
|
|
62
74
|
) -> None:
|
|
63
75
|
self.app = app
|
|
64
76
|
|
|
65
77
|
self.interval = interval
|
|
78
|
+
self.scheduler_names = scheduler_names
|
|
66
79
|
self.container = Container(self.app)
|
|
67
80
|
self.uow_provider = UnitOfWorkContextProvider(app, self.container)
|
|
68
81
|
|
|
@@ -146,7 +159,9 @@ class Scheduler:
|
|
|
146
159
|
async def run_scheduled_actions() -> None:
|
|
147
160
|
|
|
148
161
|
async with self.lifceycle():
|
|
149
|
-
scheduled_actions = extract_scheduled_actions(
|
|
162
|
+
scheduled_actions = extract_scheduled_actions(
|
|
163
|
+
self.app, self.container, self.scheduler_names
|
|
164
|
+
)
|
|
150
165
|
|
|
151
166
|
while True:
|
|
152
167
|
for action in scheduled_actions:
|
|
@@ -31,12 +31,13 @@ from jararaca.scheduler.decorators import (
|
|
|
31
31
|
get_type_scheduled_actions,
|
|
32
32
|
)
|
|
33
33
|
from jararaca.scheduler.types import DelayedMessageData
|
|
34
|
+
from jararaca.utils.rabbitmq_utils import RabbitmqUtils
|
|
34
35
|
|
|
35
36
|
logger = logging.getLogger(__name__)
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
def extract_scheduled_actions(
|
|
39
|
-
app: Microservice, container: Container
|
|
40
|
+
app: Microservice, container: Container, scheduler_names: set[str] | None = None
|
|
40
41
|
) -> list[ScheduledActionData]:
|
|
41
42
|
scheduled_actions: list[ScheduledActionData] = []
|
|
42
43
|
for controllers in app.controllers:
|
|
@@ -44,6 +45,17 @@ def extract_scheduled_actions(
|
|
|
44
45
|
controller_instance: Any = container.get_by_type(controllers)
|
|
45
46
|
|
|
46
47
|
controller_scheduled_actions = get_type_scheduled_actions(controller_instance)
|
|
48
|
+
|
|
49
|
+
# Filter scheduled actions by name if scheduler_names is provided
|
|
50
|
+
if scheduler_names is not None:
|
|
51
|
+
filtered_actions = []
|
|
52
|
+
for action in controller_scheduled_actions:
|
|
53
|
+
# Include actions that have a name and it's in the provided set
|
|
54
|
+
if action.spec.name and action.spec.name in scheduler_names:
|
|
55
|
+
filtered_actions.append(action)
|
|
56
|
+
# Skip actions without names when filtering is active
|
|
57
|
+
controller_scheduled_actions = filtered_actions
|
|
58
|
+
|
|
47
59
|
scheduled_actions.extend(controller_scheduled_actions)
|
|
48
60
|
|
|
49
61
|
return scheduled_actions
|
|
@@ -187,9 +199,10 @@ class RabbitMQBrokerDispatcher(MessageBrokerDispatcher):
|
|
|
187
199
|
)
|
|
188
200
|
|
|
189
201
|
for sched_act_data in scheduled_actions:
|
|
190
|
-
queue = await
|
|
191
|
-
|
|
192
|
-
|
|
202
|
+
queue = await RabbitmqUtils.declare_scheduler_queue(
|
|
203
|
+
channel=channel,
|
|
204
|
+
queue_name=ScheduledAction.get_function_id(sched_act_data.callable),
|
|
205
|
+
passive=False,
|
|
193
206
|
)
|
|
194
207
|
|
|
195
208
|
await queue.bind(
|
|
@@ -226,6 +239,7 @@ class SchedulerV2:
|
|
|
226
239
|
interval: int,
|
|
227
240
|
broker_url: str,
|
|
228
241
|
backend_url: str,
|
|
242
|
+
scheduler_names: set[str] | None = None,
|
|
229
243
|
) -> None:
|
|
230
244
|
self.app = app
|
|
231
245
|
|
|
@@ -237,6 +251,7 @@ class SchedulerV2:
|
|
|
237
251
|
)
|
|
238
252
|
|
|
239
253
|
self.interval = interval
|
|
254
|
+
self.scheduler_names = scheduler_names
|
|
240
255
|
self.container = Container(self.app)
|
|
241
256
|
self.uow_provider = UnitOfWorkContextProvider(app, self.container)
|
|
242
257
|
|
|
@@ -262,7 +277,9 @@ class SchedulerV2:
|
|
|
262
277
|
"""
|
|
263
278
|
async with self.lifecycle():
|
|
264
279
|
|
|
265
|
-
scheduled_actions = extract_scheduled_actions(
|
|
280
|
+
scheduled_actions = extract_scheduled_actions(
|
|
281
|
+
self.app, self.container, self.scheduler_names
|
|
282
|
+
)
|
|
266
283
|
|
|
267
284
|
await self.broker.initialize(scheduled_actions)
|
|
268
285
|
|
|
@@ -90,3 +90,81 @@ class RabbitmqUtils:
|
|
|
90
90
|
"x-dead-letter-routing-key": cls.DEAD_LETTER_EXCHANGE,
|
|
91
91
|
},
|
|
92
92
|
)
|
|
93
|
+
|
|
94
|
+
@classmethod
|
|
95
|
+
async def declare_worker_v1_queue(
|
|
96
|
+
cls,
|
|
97
|
+
channel: AbstractChannel,
|
|
98
|
+
queue_name: str,
|
|
99
|
+
dlx_name: str,
|
|
100
|
+
dlq_name: str,
|
|
101
|
+
passive: bool = False,
|
|
102
|
+
) -> AbstractQueue:
|
|
103
|
+
"""
|
|
104
|
+
Declare a worker v1 queue with custom dead letter exchange and routing key.
|
|
105
|
+
"""
|
|
106
|
+
return await channel.declare_queue(
|
|
107
|
+
passive=passive,
|
|
108
|
+
name=queue_name,
|
|
109
|
+
arguments={
|
|
110
|
+
"x-dead-letter-exchange": dlx_name,
|
|
111
|
+
"x-dead-letter-routing-key": dlq_name,
|
|
112
|
+
},
|
|
113
|
+
durable=True,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
async def declare_scheduler_queue(
|
|
118
|
+
cls,
|
|
119
|
+
channel: AbstractChannel,
|
|
120
|
+
queue_name: str,
|
|
121
|
+
passive: bool = False,
|
|
122
|
+
) -> AbstractQueue:
|
|
123
|
+
"""
|
|
124
|
+
Declare a scheduler queue with simple durable configuration.
|
|
125
|
+
"""
|
|
126
|
+
return await channel.declare_queue(
|
|
127
|
+
name=queue_name,
|
|
128
|
+
durable=True,
|
|
129
|
+
passive=passive,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
@classmethod
|
|
133
|
+
async def delete_queue(
|
|
134
|
+
cls,
|
|
135
|
+
channel: AbstractChannel,
|
|
136
|
+
queue_name: str,
|
|
137
|
+
if_unused: bool = False,
|
|
138
|
+
if_empty: bool = False,
|
|
139
|
+
) -> None:
|
|
140
|
+
"""
|
|
141
|
+
Delete a queue.
|
|
142
|
+
"""
|
|
143
|
+
try:
|
|
144
|
+
await channel.queue_delete(
|
|
145
|
+
queue_name=queue_name,
|
|
146
|
+
if_unused=if_unused,
|
|
147
|
+
if_empty=if_empty,
|
|
148
|
+
)
|
|
149
|
+
except Exception:
|
|
150
|
+
# Queue might not exist, which is fine
|
|
151
|
+
pass
|
|
152
|
+
|
|
153
|
+
@classmethod
|
|
154
|
+
async def delete_exchange(
|
|
155
|
+
cls,
|
|
156
|
+
channel: AbstractChannel,
|
|
157
|
+
exchange_name: str,
|
|
158
|
+
if_unused: bool = False,
|
|
159
|
+
) -> None:
|
|
160
|
+
"""
|
|
161
|
+
Delete an exchange.
|
|
162
|
+
"""
|
|
163
|
+
try:
|
|
164
|
+
await channel.exchange_delete(
|
|
165
|
+
exchange_name=exchange_name,
|
|
166
|
+
if_unused=if_unused,
|
|
167
|
+
)
|
|
168
|
+
except Exception:
|
|
169
|
+
# Exchange might not exist, which is fine
|
|
170
|
+
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg
RENAMED
|
File without changes
|
{jararaca-0.3.11a7 → jararaca-0.3.11a8}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.webp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/persistence/interceptors/aiosqa_interceptor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jararaca-0.3.11a7 → jararaca-0.3.11a8}/src/jararaca/presentation/websocket/websocket_interceptor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|