jararaca 0.3.11a6__py3-none-any.whl → 0.3.11a8__py3-none-any.whl
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/cli.py +187 -18
- jararaca/messagebus/decorators.py +2 -0
- jararaca/messagebus/worker.py +28 -10
- jararaca/messagebus/worker_v2.py +23 -1
- jararaca/scheduler/decorators.py +7 -0
- jararaca/scheduler/scheduler.py +17 -2
- jararaca/scheduler/scheduler_v2.py +22 -7
- jararaca/utils/rabbitmq_utils.py +82 -4
- {jararaca-0.3.11a6.dist-info → jararaca-0.3.11a8.dist-info}/METADATA +1 -1
- {jararaca-0.3.11a6.dist-info → jararaca-0.3.11a8.dist-info}/RECORD +13 -13
- {jararaca-0.3.11a6.dist-info → jararaca-0.3.11a8.dist-info}/LICENSE +0 -0
- {jararaca-0.3.11a6.dist-info → jararaca-0.3.11a8.dist-info}/WHEEL +0 -0
- {jararaca-0.3.11a6.dist-info → jararaca-0.3.11a8.dist-info}/entry_points.txt +0 -0
jararaca/cli.py
CHANGED
|
@@ -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,7 +85,12 @@ async def declare_worker_infrastructure(
|
|
|
82
85
|
connection = await aio_pika.connect(url)
|
|
83
86
|
channel = await connection.channel()
|
|
84
87
|
|
|
85
|
-
|
|
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)
|
|
86
94
|
|
|
87
95
|
# Declare main exchange
|
|
88
96
|
main_ex = await RabbitmqUtils.declare_main_exchange(
|
|
@@ -112,17 +120,27 @@ async def declare_worker_infrastructure(
|
|
|
112
120
|
handlers, _ = factory(instance)
|
|
113
121
|
|
|
114
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
|
+
|
|
115
131
|
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.instance_callable.__module__}.{handler.instance_callable.__qualname__}"
|
|
116
132
|
routing_key = f"{handler.message_type.MESSAGE_TOPIC}.#"
|
|
117
133
|
|
|
118
|
-
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,
|
|
119
143
|
passive=passive_declare,
|
|
120
|
-
name=queue_name,
|
|
121
|
-
arguments={
|
|
122
|
-
"x-dead-letter-exchange": dlx.name,
|
|
123
|
-
"x-dead-letter-routing-key": dlq.name,
|
|
124
|
-
},
|
|
125
|
-
durable=True,
|
|
126
144
|
)
|
|
127
145
|
|
|
128
146
|
await queue.bind(exchange=main_ex, routing_key=routing_key)
|
|
@@ -136,6 +154,8 @@ async def declare_worker_v2_infrastructure(
|
|
|
136
154
|
broker_url: str,
|
|
137
155
|
app: Microservice,
|
|
138
156
|
passive_declare: bool = False,
|
|
157
|
+
handler_names: set[str] | None = None,
|
|
158
|
+
force: bool = False,
|
|
139
159
|
) -> None:
|
|
140
160
|
"""
|
|
141
161
|
Declare the infrastructure (exchanges and queues) for worker v2.
|
|
@@ -159,7 +179,12 @@ async def declare_worker_v2_infrastructure(
|
|
|
159
179
|
connection = await aio_pika.connect(broker_url)
|
|
160
180
|
channel = await connection.channel()
|
|
161
181
|
|
|
162
|
-
|
|
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)
|
|
163
188
|
|
|
164
189
|
# Declare main exchange
|
|
165
190
|
await RabbitmqUtils.declare_main_exchange(
|
|
@@ -192,9 +217,21 @@ async def declare_worker_v2_infrastructure(
|
|
|
192
217
|
|
|
193
218
|
# Declare queues for message handlers
|
|
194
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
|
+
|
|
195
228
|
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.instance_callable.__module__}.{handler.instance_callable.__qualname__}"
|
|
196
229
|
routing_key = f"{handler.message_type.MESSAGE_TOPIC}.#"
|
|
197
230
|
|
|
231
|
+
# Force delete queue if requested
|
|
232
|
+
if force:
|
|
233
|
+
await RabbitmqUtils.delete_queue(channel, queue_name)
|
|
234
|
+
|
|
198
235
|
queue = await RabbitmqUtils.declare_queue(
|
|
199
236
|
channel=channel, queue_name=queue_name, passive=passive_declare
|
|
200
237
|
)
|
|
@@ -208,6 +245,10 @@ async def declare_worker_v2_infrastructure(
|
|
|
208
245
|
queue_name = f"{scheduled_action.callable.__module__}.{scheduled_action.callable.__qualname__}"
|
|
209
246
|
routing_key = queue_name
|
|
210
247
|
|
|
248
|
+
# Force delete queue if requested
|
|
249
|
+
if force:
|
|
250
|
+
await RabbitmqUtils.delete_queue(channel, queue_name)
|
|
251
|
+
|
|
211
252
|
queue = await RabbitmqUtils.declare_queue(
|
|
212
253
|
channel=channel, queue_name=queue_name, passive=passive_declare
|
|
213
254
|
)
|
|
@@ -224,6 +265,8 @@ async def declare_scheduler_v2_infrastructure(
|
|
|
224
265
|
broker_url: str,
|
|
225
266
|
app: Microservice,
|
|
226
267
|
passive_declare: bool = False,
|
|
268
|
+
scheduler_names: set[str] | None = None,
|
|
269
|
+
force: bool = False,
|
|
227
270
|
) -> None:
|
|
228
271
|
"""
|
|
229
272
|
Declare the infrastructure (exchanges and queues) for scheduler v2.
|
|
@@ -249,7 +292,9 @@ async def declare_scheduler_v2_infrastructure(
|
|
|
249
292
|
connection = await aio_pika.connect(broker_url)
|
|
250
293
|
channel = await connection.channel()
|
|
251
294
|
|
|
252
|
-
|
|
295
|
+
# Force delete exchange if requested
|
|
296
|
+
if force:
|
|
297
|
+
await RabbitmqUtils.delete_exchange(channel, exchange)
|
|
253
298
|
|
|
254
299
|
# Declare exchange for scheduler
|
|
255
300
|
await channel.declare_exchange(
|
|
@@ -275,13 +320,29 @@ async def declare_scheduler_v2_infrastructure(
|
|
|
275
320
|
instance: Any = container.get_by_type(instance_type)
|
|
276
321
|
factory = controller.get_messagebus_factory()
|
|
277
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
|
+
|
|
278
334
|
scheduled_actions.extend(actions)
|
|
279
335
|
|
|
280
336
|
for scheduled_action in scheduled_actions:
|
|
281
337
|
queue_name = ScheduledAction.get_function_id(scheduled_action.callable)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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,
|
|
285
346
|
passive=passive_declare,
|
|
286
347
|
)
|
|
287
348
|
await queue.bind(
|
|
@@ -334,6 +395,11 @@ def cli() -> None:
|
|
|
334
395
|
is_flag=True,
|
|
335
396
|
default=False,
|
|
336
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
|
+
)
|
|
337
403
|
def worker(
|
|
338
404
|
app_path: str,
|
|
339
405
|
url: str,
|
|
@@ -342,6 +408,7 @@ def worker(
|
|
|
342
408
|
exchange: str,
|
|
343
409
|
prefetch_count: int,
|
|
344
410
|
passive_declare: bool,
|
|
411
|
+
handlers: str | None,
|
|
345
412
|
) -> None:
|
|
346
413
|
|
|
347
414
|
app = find_microservice_by_module_path(app_path)
|
|
@@ -368,6 +435,11 @@ def worker(
|
|
|
368
435
|
|
|
369
436
|
url = parsed_url.geturl()
|
|
370
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
|
+
|
|
371
443
|
config = worker_v1.AioPikaWorkerConfig(
|
|
372
444
|
url=url,
|
|
373
445
|
exchange=exchange,
|
|
@@ -376,6 +448,7 @@ def worker(
|
|
|
376
448
|
|
|
377
449
|
worker_v1.MessageBusWorker(app, config=config).start_sync(
|
|
378
450
|
passive_declare=passive_declare,
|
|
451
|
+
handler_names=handler_names,
|
|
379
452
|
)
|
|
380
453
|
|
|
381
454
|
|
|
@@ -395,14 +468,27 @@ def worker(
|
|
|
395
468
|
type=str,
|
|
396
469
|
envvar="BACKEND_URL",
|
|
397
470
|
)
|
|
398
|
-
|
|
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:
|
|
399
479
|
|
|
400
480
|
app = find_microservice_by_module_path(app_path)
|
|
401
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
|
+
|
|
402
487
|
worker_v2_mod.MessageBusWorker(
|
|
403
488
|
app=app,
|
|
404
489
|
broker_url=broker_url,
|
|
405
490
|
backend_url=backend_url,
|
|
491
|
+
handler_names=handler_names,
|
|
406
492
|
).start_sync()
|
|
407
493
|
|
|
408
494
|
|
|
@@ -455,13 +541,26 @@ def server(app_path: str, host: str, port: int) -> None:
|
|
|
455
541
|
type=int,
|
|
456
542
|
default=1,
|
|
457
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
|
+
)
|
|
458
549
|
def scheduler(
|
|
459
550
|
app_path: str,
|
|
460
551
|
interval: int,
|
|
552
|
+
schedulers: str | None = None,
|
|
461
553
|
) -> None:
|
|
462
554
|
app = find_microservice_by_module_path(app_path)
|
|
463
555
|
|
|
464
|
-
|
|
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()
|
|
465
564
|
|
|
466
565
|
|
|
467
566
|
@cli.command()
|
|
@@ -485,19 +584,34 @@ def scheduler(
|
|
|
485
584
|
type=str,
|
|
486
585
|
required=True,
|
|
487
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
|
+
)
|
|
488
592
|
def scheduler_v2(
|
|
489
593
|
interval: int,
|
|
490
594
|
broker_url: str,
|
|
491
595
|
backend_url: str,
|
|
492
596
|
app_path: str,
|
|
597
|
+
schedulers: str | None = None,
|
|
493
598
|
) -> None:
|
|
494
599
|
|
|
495
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
|
+
|
|
496
609
|
scheduler = SchedulerV2(
|
|
497
610
|
app=app,
|
|
498
611
|
interval=interval,
|
|
499
612
|
backend_url=backend_url,
|
|
500
613
|
broker_url=broker_url,
|
|
614
|
+
scheduler_names=scheduler_names,
|
|
501
615
|
)
|
|
502
616
|
scheduler.run()
|
|
503
617
|
|
|
@@ -746,11 +860,24 @@ def gen_entity(entity_name: str, file_path: StreamWriter) -> None:
|
|
|
746
860
|
default=False,
|
|
747
861
|
help="Use passive declarations (check if infrastructure exists without creating it)",
|
|
748
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
|
+
)
|
|
749
874
|
def declare_queues_v1(
|
|
750
875
|
app_path: str,
|
|
751
876
|
broker_url: str | None,
|
|
752
877
|
exchange: str,
|
|
753
878
|
passive_declare: bool,
|
|
879
|
+
handlers: str | None,
|
|
880
|
+
force: bool,
|
|
754
881
|
) -> None:
|
|
755
882
|
"""
|
|
756
883
|
Declare RabbitMQ infrastructure (exchanges and queues) for worker v1.
|
|
@@ -785,13 +912,20 @@ def declare_queues_v1(
|
|
|
785
912
|
)
|
|
786
913
|
return
|
|
787
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
|
+
|
|
788
922
|
click.echo(
|
|
789
923
|
f"→ Declaring worker v1 infrastructure (URL: {broker_url}, Exchange: {exchange})"
|
|
790
924
|
)
|
|
791
925
|
|
|
792
926
|
try:
|
|
793
927
|
await declare_worker_infrastructure(
|
|
794
|
-
broker_url, exchange, app, passive_declare
|
|
928
|
+
broker_url, exchange, app, passive_declare, handler_names, force
|
|
795
929
|
)
|
|
796
930
|
click.echo("✓ Worker v1 infrastructure declared successfully!")
|
|
797
931
|
except Exception as e:
|
|
@@ -827,11 +961,30 @@ def declare_queues_v1(
|
|
|
827
961
|
default=False,
|
|
828
962
|
help="Use passive declarations (check if infrastructure exists without creating it)",
|
|
829
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
|
+
)
|
|
830
980
|
def declare_queues_v2(
|
|
831
981
|
app_path: str,
|
|
832
982
|
broker_url: str | None,
|
|
833
983
|
exchange: str,
|
|
834
984
|
passive_declare: bool,
|
|
985
|
+
handlers: str | None,
|
|
986
|
+
schedulers: str | None,
|
|
987
|
+
force: bool,
|
|
835
988
|
) -> None:
|
|
836
989
|
"""
|
|
837
990
|
Declare RabbitMQ infrastructure (exchanges and queues) for worker v2 and scheduler v2.
|
|
@@ -866,6 +1019,20 @@ def declare_queues_v2(
|
|
|
866
1019
|
)
|
|
867
1020
|
return
|
|
868
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
|
+
|
|
869
1036
|
# For v2, create the broker URL with exchange parameter
|
|
870
1037
|
v2_broker_url = f"{broker_url}?exchange={exchange}"
|
|
871
1038
|
|
|
@@ -874,9 +1041,11 @@ def declare_queues_v2(
|
|
|
874
1041
|
|
|
875
1042
|
try:
|
|
876
1043
|
await asyncio.gather(
|
|
877
|
-
declare_worker_v2_infrastructure(
|
|
1044
|
+
declare_worker_v2_infrastructure(
|
|
1045
|
+
v2_broker_url, app, passive_declare, handler_names, force
|
|
1046
|
+
),
|
|
878
1047
|
declare_scheduler_v2_infrastructure(
|
|
879
|
-
v2_broker_url, app, passive_declare
|
|
1048
|
+
v2_broker_url, app, passive_declare, scheduler_names, force
|
|
880
1049
|
),
|
|
881
1050
|
)
|
|
882
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]]
|
jararaca/messagebus/worker.py
CHANGED
|
@@ -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):
|
jararaca/messagebus/worker_v2.py
CHANGED
|
@@ -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"
|
jararaca/scheduler/decorators.py
CHANGED
|
@@ -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
|
jararaca/scheduler/scheduler.py
CHANGED
|
@@ -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
|
|
@@ -179,8 +191,6 @@ class RabbitMQBrokerDispatcher(MessageBrokerDispatcher):
|
|
|
179
191
|
|
|
180
192
|
async with self.channel_pool.acquire() as channel:
|
|
181
193
|
|
|
182
|
-
await channel.set_qos(prefetch_count=1)
|
|
183
|
-
|
|
184
194
|
await channel.declare_exchange(
|
|
185
195
|
name=self.exchange,
|
|
186
196
|
type="topic",
|
|
@@ -189,9 +199,10 @@ class RabbitMQBrokerDispatcher(MessageBrokerDispatcher):
|
|
|
189
199
|
)
|
|
190
200
|
|
|
191
201
|
for sched_act_data in scheduled_actions:
|
|
192
|
-
queue = await
|
|
193
|
-
|
|
194
|
-
|
|
202
|
+
queue = await RabbitmqUtils.declare_scheduler_queue(
|
|
203
|
+
channel=channel,
|
|
204
|
+
queue_name=ScheduledAction.get_function_id(sched_act_data.callable),
|
|
205
|
+
passive=False,
|
|
195
206
|
)
|
|
196
207
|
|
|
197
208
|
await queue.bind(
|
|
@@ -228,6 +239,7 @@ class SchedulerV2:
|
|
|
228
239
|
interval: int,
|
|
229
240
|
broker_url: str,
|
|
230
241
|
backend_url: str,
|
|
242
|
+
scheduler_names: set[str] | None = None,
|
|
231
243
|
) -> None:
|
|
232
244
|
self.app = app
|
|
233
245
|
|
|
@@ -239,6 +251,7 @@ class SchedulerV2:
|
|
|
239
251
|
)
|
|
240
252
|
|
|
241
253
|
self.interval = interval
|
|
254
|
+
self.scheduler_names = scheduler_names
|
|
242
255
|
self.container = Container(self.app)
|
|
243
256
|
self.uow_provider = UnitOfWorkContextProvider(app, self.container)
|
|
244
257
|
|
|
@@ -264,7 +277,9 @@ class SchedulerV2:
|
|
|
264
277
|
"""
|
|
265
278
|
async with self.lifecycle():
|
|
266
279
|
|
|
267
|
-
scheduled_actions = extract_scheduled_actions(
|
|
280
|
+
scheduled_actions = extract_scheduled_actions(
|
|
281
|
+
self.app, self.container, self.scheduler_names
|
|
282
|
+
)
|
|
268
283
|
|
|
269
284
|
await self.broker.initialize(scheduled_actions)
|
|
270
285
|
|
jararaca/utils/rabbitmq_utils.py
CHANGED
|
@@ -13,7 +13,7 @@ class RabbitmqUtils:
|
|
|
13
13
|
"""
|
|
14
14
|
Declare a Dead Letter Exchange (DLX) for the given channel.
|
|
15
15
|
"""
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
return await channel.declare_exchange(
|
|
18
18
|
cls.DEAD_LETTER_EXCHANGE,
|
|
19
19
|
passive=passive,
|
|
@@ -29,7 +29,7 @@ class RabbitmqUtils:
|
|
|
29
29
|
"""
|
|
30
30
|
Declare a Dead Letter Queue (DLQ) for the given queue.
|
|
31
31
|
"""
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
return await channel.declare_queue(
|
|
34
34
|
cls.DEAD_LETTER_QUEUE,
|
|
35
35
|
durable=True,
|
|
@@ -61,7 +61,7 @@ class RabbitmqUtils:
|
|
|
61
61
|
"""
|
|
62
62
|
Declare a main exchange for the given channel.
|
|
63
63
|
"""
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
return await channel.declare_exchange(
|
|
66
66
|
exchange_name,
|
|
67
67
|
passive=passive,
|
|
@@ -80,7 +80,7 @@ class RabbitmqUtils:
|
|
|
80
80
|
"""
|
|
81
81
|
Declare a queue with the given name and properties.
|
|
82
82
|
"""
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
return await channel.declare_queue(
|
|
85
85
|
queue_name,
|
|
86
86
|
passive=passive,
|
|
@@ -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
|
|
@@ -3,7 +3,7 @@ jararaca/__main__.py,sha256=-O3vsB5lHdqNFjUtoELDF81IYFtR-DSiiFMzRaiSsv4,67
|
|
|
3
3
|
jararaca/broker_backend/__init__.py,sha256=GzEIuHR1xzgCJD4FE3harNjoaYzxHMHoEL0_clUaC-k,3528
|
|
4
4
|
jararaca/broker_backend/mapper.py,sha256=vTsi7sWpNvlga1PWPFg0rCJ5joJ0cdzykkIc2Tuvenc,696
|
|
5
5
|
jararaca/broker_backend/redis_broker_backend.py,sha256=a7DHchy3NAiD71Ix8SwmQOUnniu7uup-Woa4ON_4J7I,5786
|
|
6
|
-
jararaca/cli.py,sha256
|
|
6
|
+
jararaca/cli.py,sha256=-fFnf67N7DFwEg-cfEjWj5qrIEf2hzrzHbLm6x3xpTw,30992
|
|
7
7
|
jararaca/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
jararaca/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
jararaca/core/providers.py,sha256=wktH84FK7c1s2wNq-fudf1uMfi3CQBR0neU2czJ_L0U,434
|
|
@@ -14,14 +14,14 @@ jararaca/lifecycle.py,sha256=qKlzLQQioS8QkxNJ_FC_5WbmT77cNbc_S7OcQeOoHkI,1895
|
|
|
14
14
|
jararaca/messagebus/__init__.py,sha256=5jAqPqdcEMYBfQyfZDWPnplYdrfMyJLMcacf3qLyUhk,56
|
|
15
15
|
jararaca/messagebus/bus_message_controller.py,sha256=Xd_qwnX5jUvgBTCarHR36fvtol9lPTsYp2IIGKyQQaE,1487
|
|
16
16
|
jararaca/messagebus/consumers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
jararaca/messagebus/decorators.py,sha256=
|
|
17
|
+
jararaca/messagebus/decorators.py,sha256=oKFAavGWDTLMQCg6NyWF8U5zpWNvccSZ8H2UVXlSRGE,5905
|
|
18
18
|
jararaca/messagebus/interceptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
19
|
jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py,sha256=_DEHwIH9LYsA26Hu1mo9oHzLZuATgjilU9E3o-ecDjs,6520
|
|
20
20
|
jararaca/messagebus/interceptors/publisher_interceptor.py,sha256=ojy1bRhqMgrkQljcGGS8cd8-8pUjL8ZHjIUkdmaAnNM,1325
|
|
21
21
|
jararaca/messagebus/message.py,sha256=U6cyd2XknX8mtm0333slz5fanky2PFLWCmokAO56vvU,819
|
|
22
22
|
jararaca/messagebus/publisher.py,sha256=JTkxdKbvxvDWT8nK8PVEyyX061vYYbKQMxRHXrZtcEY,2173
|
|
23
|
-
jararaca/messagebus/worker.py,sha256=
|
|
24
|
-
jararaca/messagebus/worker_v2.py,sha256=
|
|
23
|
+
jararaca/messagebus/worker.py,sha256=cj2Tn2l0kyc-NO6zn6C8yvT-sSi1aFZluXSLTUqfaAI,14701
|
|
24
|
+
jararaca/messagebus/worker_v2.py,sha256=QMw40YfOm3kCuuHlyGKSkx50aVrwBvhJRt5L4Twgvqw,21653
|
|
25
25
|
jararaca/microservice.py,sha256=jTGzkoJcco1nXwZZDeHRwEHAu_Hpr5gxA_d51P49C2c,7915
|
|
26
26
|
jararaca/observability/decorators.py,sha256=MOIr2PttPYYvRwEdfQZEwD5RxKHOTv8UEy9n1YQVoKw,2281
|
|
27
27
|
jararaca/observability/interceptor.py,sha256=U4ZLM0f8j6Q7gMUKKnA85bnvD-Qa0ii79Qa_X8KsXAQ,1498
|
|
@@ -58,18 +58,18 @@ jararaca/rpc/http/backends/otel.py,sha256=Uc6CjHSCZ5hvnK1fNFv3ota5xzUFnvIl1JOpG3
|
|
|
58
58
|
jararaca/rpc/http/decorators.py,sha256=oUSzgMGI8w6SoKiz3GltDbd3BWAuyY60F23cdRRNeiw,11897
|
|
59
59
|
jararaca/rpc/http/httpx.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
60
|
jararaca/scheduler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
|
-
jararaca/scheduler/decorators.py,sha256=
|
|
62
|
-
jararaca/scheduler/scheduler.py,sha256=
|
|
63
|
-
jararaca/scheduler/scheduler_v2.py,sha256=
|
|
61
|
+
jararaca/scheduler/decorators.py,sha256=iyWFvPLCRh9c0YReQRemI2mLuaUv7r929So-xuKIWUs,4605
|
|
62
|
+
jararaca/scheduler/scheduler.py,sha256=1T7qKIOiU9WD2p0aJsiUW-MOArJZyUSMwpv_14ziTQM,6188
|
|
63
|
+
jararaca/scheduler/scheduler_v2.py,sha256=9o7GZRqLJj8WkBv4JLomqsDaVnrT2jeHGjN8K9YM-uA,12110
|
|
64
64
|
jararaca/scheduler/types.py,sha256=4HEQOmVIDp-BYLSzqmqSFIio1bd51WFmgFPIzPpVu04,135
|
|
65
65
|
jararaca/tools/app_config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
66
|
jararaca/tools/app_config/decorators.py,sha256=-ckkMZ1dswOmECdo1rFrZ15UAku--txaNXMp8fd1Ndk,941
|
|
67
67
|
jararaca/tools/app_config/interceptor.py,sha256=HV8h4AxqUc_ACs5do4BSVlyxlRXzx7HqJtoVO9tfRnQ,2611
|
|
68
68
|
jararaca/tools/typescript/interface_parser.py,sha256=35xbOrZDQDyTXdMrVZQ8nnFw79f28lJuLYNHAspIqi8,30492
|
|
69
69
|
jararaca/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
70
|
-
jararaca/utils/rabbitmq_utils.py,sha256=
|
|
71
|
-
jararaca-0.3.
|
|
72
|
-
jararaca-0.3.
|
|
73
|
-
jararaca-0.3.
|
|
74
|
-
jararaca-0.3.
|
|
75
|
-
jararaca-0.3.
|
|
70
|
+
jararaca/utils/rabbitmq_utils.py,sha256=IeKRc5K3Ml6yWFmdcL7r99c9tgyeyjlr3o_ZWtDBT9M,4651
|
|
71
|
+
jararaca-0.3.11a8.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
72
|
+
jararaca-0.3.11a8.dist-info/METADATA,sha256=Twd_9r877lTkrkAvB77ihCU2gKIiR84pzwGViRvG770,4997
|
|
73
|
+
jararaca-0.3.11a8.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
74
|
+
jararaca-0.3.11a8.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
|
|
75
|
+
jararaca-0.3.11a8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|