jararaca 0.3.11a3__py3-none-any.whl → 0.3.11a5__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/__init__.py +73 -2
- jararaca/cli.py +2 -2
- jararaca/core/uow.py +17 -12
- jararaca/messagebus/decorators.py +31 -30
- jararaca/messagebus/interceptors/publisher_interceptor.py +5 -3
- jararaca/messagebus/worker.py +13 -6
- jararaca/messagebus/worker_v2.py +21 -26
- jararaca/microservice.py +61 -18
- jararaca/observability/decorators.py +7 -3
- jararaca/observability/interceptor.py +4 -2
- jararaca/observability/providers/otel.py +14 -10
- jararaca/persistence/base.py +2 -1
- jararaca/persistence/interceptors/aiosqa_interceptor.py +167 -16
- jararaca/presentation/decorators.py +96 -10
- jararaca/presentation/server.py +31 -4
- jararaca/presentation/websocket/websocket_interceptor.py +4 -2
- jararaca/reflect/__init__.py +0 -0
- jararaca/reflect/controller_inspect.py +75 -0
- jararaca/{tools → reflect}/metadata.py +25 -5
- jararaca/scheduler/decorators.py +48 -20
- jararaca/scheduler/scheduler.py +27 -22
- jararaca/scheduler/scheduler_v2.py +20 -16
- jararaca/tools/app_config/interceptor.py +4 -2
- {jararaca-0.3.11a3.dist-info → jararaca-0.3.11a5.dist-info}/METADATA +2 -1
- {jararaca-0.3.11a3.dist-info → jararaca-0.3.11a5.dist-info}/RECORD +28 -26
- {jararaca-0.3.11a3.dist-info → jararaca-0.3.11a5.dist-info}/LICENSE +0 -0
- {jararaca-0.3.11a3.dist-info → jararaca-0.3.11a5.dist-info}/WHEEL +0 -0
- {jararaca-0.3.11a3.dist-info → jararaca-0.3.11a5.dist-info}/entry_points.txt +0 -0
jararaca/__init__.py
CHANGED
|
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
|
|
11
11
|
retry_later,
|
|
12
12
|
use_bus_message_controller,
|
|
13
13
|
)
|
|
14
|
-
from jararaca.microservice import
|
|
14
|
+
from jararaca.microservice import AppInterceptor, AppTransactionContext
|
|
15
15
|
from jararaca.observability.interceptor import ObservabilityInterceptor
|
|
16
16
|
from jararaca.observability.providers.otel import OtelObservabilityProvider
|
|
17
17
|
from jararaca.persistence.sort_filter import (
|
|
@@ -32,6 +32,17 @@ if TYPE_CHECKING:
|
|
|
32
32
|
raises_500_on,
|
|
33
33
|
raises_http_exception_on,
|
|
34
34
|
)
|
|
35
|
+
from jararaca.reflect.controller_inspect import (
|
|
36
|
+
ControllerMemberReflect,
|
|
37
|
+
ControllerReflect,
|
|
38
|
+
)
|
|
39
|
+
from jararaca.reflect.metadata import (
|
|
40
|
+
SetMetadata,
|
|
41
|
+
get_all_metadata,
|
|
42
|
+
get_metadata,
|
|
43
|
+
get_metadata_value,
|
|
44
|
+
provide_metadata,
|
|
45
|
+
)
|
|
35
46
|
from jararaca.rpc.http.backends.httpx import HTTPXHttpRPCAsyncBackend
|
|
36
47
|
from jararaca.rpc.http.backends.otel import TracedRequestMiddleware
|
|
37
48
|
from jararaca.rpc.http.decorators import Body
|
|
@@ -68,12 +79,22 @@ if TYPE_CHECKING:
|
|
|
68
79
|
from .messagebus.message import Message, MessageOf
|
|
69
80
|
from .messagebus.publisher import use_publisher
|
|
70
81
|
from .messagebus.worker import MessageBusWorker
|
|
71
|
-
from .microservice import
|
|
82
|
+
from .microservice import (
|
|
83
|
+
Microservice,
|
|
84
|
+
use_app_context,
|
|
85
|
+
use_app_transaction_context,
|
|
86
|
+
use_app_tx_ctx_data,
|
|
87
|
+
use_current_container,
|
|
88
|
+
)
|
|
72
89
|
from .persistence.base import T_BASEMODEL, BaseEntity
|
|
73
90
|
from .persistence.interceptors.aiosqa_interceptor import (
|
|
74
91
|
AIOSQAConfig,
|
|
75
92
|
AIOSqlAlchemySessionInterceptor,
|
|
93
|
+
providing_new_session,
|
|
94
|
+
providing_session,
|
|
95
|
+
providing_transaction,
|
|
76
96
|
use_session,
|
|
97
|
+
use_transaction,
|
|
77
98
|
)
|
|
78
99
|
from .persistence.utilities import (
|
|
79
100
|
CriteriaBasedAttributeQueryInjector,
|
|
@@ -118,6 +139,11 @@ if TYPE_CHECKING:
|
|
|
118
139
|
from .tools.app_config.interceptor import AppConfigurationInterceptor
|
|
119
140
|
|
|
120
141
|
__all__ = [
|
|
142
|
+
"SetMetadata",
|
|
143
|
+
"provide_metadata",
|
|
144
|
+
"get_metadata",
|
|
145
|
+
"get_all_metadata",
|
|
146
|
+
"get_metadata_value",
|
|
121
147
|
"RedisMessageBrokerBackend",
|
|
122
148
|
"FilterRuleApplier",
|
|
123
149
|
"SortRuleApplier",
|
|
@@ -191,6 +217,11 @@ if TYPE_CHECKING:
|
|
|
191
217
|
"Container",
|
|
192
218
|
"WebSocketInterceptor",
|
|
193
219
|
"use_session",
|
|
220
|
+
"use_transaction",
|
|
221
|
+
"providing_session",
|
|
222
|
+
"provide_session",
|
|
223
|
+
"providing_transaction",
|
|
224
|
+
"providing_new_session",
|
|
194
225
|
"Post",
|
|
195
226
|
"Get",
|
|
196
227
|
"Patch",
|
|
@@ -212,7 +243,12 @@ if TYPE_CHECKING:
|
|
|
212
243
|
"HttpRpcClientBuilder",
|
|
213
244
|
"HTTPXHttpRPCAsyncBackend",
|
|
214
245
|
"use_app_context",
|
|
246
|
+
"use_app_transaction_context",
|
|
247
|
+
"use_app_tx_ctx_data",
|
|
248
|
+
"AppTransactionContext",
|
|
215
249
|
"AppContext",
|
|
250
|
+
"ControllerMemberReflect",
|
|
251
|
+
"ControllerReflect",
|
|
216
252
|
"AppInterceptor",
|
|
217
253
|
"OtelObservabilityProvider",
|
|
218
254
|
]
|
|
@@ -220,6 +256,11 @@ if TYPE_CHECKING:
|
|
|
220
256
|
__SPEC_PARENT__: str = __spec__.parent # type: ignore
|
|
221
257
|
# A mapping of {<member name>: (package, <module name>)} defining dynamic imports
|
|
222
258
|
_dynamic_imports: "dict[str, tuple[str, str, str | None]]" = {
|
|
259
|
+
"SetMetadata": (__SPEC_PARENT__, "reflect.metadata", None),
|
|
260
|
+
"provide_metadata": (__SPEC_PARENT__, "reflect.metadata", None),
|
|
261
|
+
"get_metadata": (__SPEC_PARENT__, "reflect.metadata", None),
|
|
262
|
+
"get_all_metadata": (__SPEC_PARENT__, "reflect.metadata", None),
|
|
263
|
+
"get_metadata_value": (__SPEC_PARENT__, "reflect.metadata", None),
|
|
223
264
|
"RedisMessageBrokerBackend": (
|
|
224
265
|
__SPEC_PARENT__,
|
|
225
266
|
"broker_backend.redis_broker_backend",
|
|
@@ -335,6 +376,31 @@ _dynamic_imports: "dict[str, tuple[str, str, str | None]]" = {
|
|
|
335
376
|
"persistence.interceptors.aiosqa_interceptor",
|
|
336
377
|
None,
|
|
337
378
|
),
|
|
379
|
+
"use_transaction": (
|
|
380
|
+
__SPEC_PARENT__,
|
|
381
|
+
"persistence.interceptors.aiosqa_interceptor",
|
|
382
|
+
None,
|
|
383
|
+
),
|
|
384
|
+
"providing_session": (
|
|
385
|
+
__SPEC_PARENT__,
|
|
386
|
+
"persistence.interceptors.aiosqa_interceptor",
|
|
387
|
+
None,
|
|
388
|
+
),
|
|
389
|
+
"provide_session": (
|
|
390
|
+
__SPEC_PARENT__,
|
|
391
|
+
"persistence.interceptors.aiosqa_interceptor",
|
|
392
|
+
None,
|
|
393
|
+
),
|
|
394
|
+
"providing_new_session": (
|
|
395
|
+
__SPEC_PARENT__,
|
|
396
|
+
"persistence.interceptors.aiosqa_interceptor",
|
|
397
|
+
None,
|
|
398
|
+
),
|
|
399
|
+
"providing_transaction": (
|
|
400
|
+
__SPEC_PARENT__,
|
|
401
|
+
"persistence.interceptors.aiosqa_interceptor",
|
|
402
|
+
None,
|
|
403
|
+
),
|
|
338
404
|
"Post": (__SPEC_PARENT__, "presentation.decorators", None),
|
|
339
405
|
"Get": (__SPEC_PARENT__, "presentation.decorators", None),
|
|
340
406
|
"Patch": (__SPEC_PARENT__, "presentation.decorators", None),
|
|
@@ -375,8 +441,13 @@ _dynamic_imports: "dict[str, tuple[str, str, str | None]]" = {
|
|
|
375
441
|
"HttpRpcClientBuilder": (__SPEC_PARENT__, "rpc.http.decorators", None),
|
|
376
442
|
"HTTPXHttpRPCAsyncBackend": (__SPEC_PARENT__, "rpc.http.backends.httpx", None),
|
|
377
443
|
"use_app_context": (__SPEC_PARENT__, "microservice", None),
|
|
444
|
+
"use_app_transaction_context": (__SPEC_PARENT__, "microservice", None),
|
|
445
|
+
"use_app_tx_ctx_data": (__SPEC_PARENT__, "microservice", None),
|
|
378
446
|
"AppContext": (__SPEC_PARENT__, "microservice", None),
|
|
379
447
|
"AppInterceptor": (__SPEC_PARENT__, "microservice", None),
|
|
448
|
+
"AppTransactionContext": (__SPEC_PARENT__, "microservice", None),
|
|
449
|
+
"ControllerMemberReflect": (__SPEC_PARENT__, "reflect.controller_inspect", None),
|
|
450
|
+
"ControllerReflect": (__SPEC_PARENT__, "reflect.controller_inspect", None),
|
|
380
451
|
}
|
|
381
452
|
|
|
382
453
|
|
jararaca/cli.py
CHANGED
|
@@ -112,7 +112,7 @@ async def declare_worker_infrastructure(
|
|
|
112
112
|
handlers, _ = factory(instance)
|
|
113
113
|
|
|
114
114
|
for handler in handlers:
|
|
115
|
-
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.
|
|
115
|
+
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.instance_callable.__module__}.{handler.instance_callable.__qualname__}"
|
|
116
116
|
routing_key = f"{handler.message_type.MESSAGE_TOPIC}.#"
|
|
117
117
|
|
|
118
118
|
queue = await channel.declare_queue(
|
|
@@ -192,7 +192,7 @@ async def declare_worker_v2_infrastructure(
|
|
|
192
192
|
|
|
193
193
|
# Declare queues for message handlers
|
|
194
194
|
for handler in handlers:
|
|
195
|
-
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.
|
|
195
|
+
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.instance_callable.__module__}.{handler.instance_callable.__qualname__}"
|
|
196
196
|
routing_key = f"{handler.message_type.MESSAGE_TOPIC}.#"
|
|
197
197
|
|
|
198
198
|
queue = await RabbitmqUtils.declare_queue(
|
jararaca/core/uow.py
CHANGED
|
@@ -2,13 +2,14 @@ from contextlib import asynccontextmanager
|
|
|
2
2
|
from typing import AsyncGenerator, Sequence
|
|
3
3
|
|
|
4
4
|
from jararaca.microservice import (
|
|
5
|
-
AppContext,
|
|
6
5
|
AppInterceptor,
|
|
6
|
+
AppTransactionContext,
|
|
7
7
|
Container,
|
|
8
8
|
Microservice,
|
|
9
9
|
provide_app_context,
|
|
10
10
|
provide_container,
|
|
11
11
|
)
|
|
12
|
+
from jararaca.reflect.metadata import provide_metadata
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class ContainerInterceptor(AppInterceptor):
|
|
@@ -17,7 +18,9 @@ class ContainerInterceptor(AppInterceptor):
|
|
|
17
18
|
self.container = container
|
|
18
19
|
|
|
19
20
|
@asynccontextmanager
|
|
20
|
-
async def intercept(
|
|
21
|
+
async def intercept(
|
|
22
|
+
self, app_context: AppTransactionContext
|
|
23
|
+
) -> AsyncGenerator[None, None]:
|
|
21
24
|
|
|
22
25
|
with provide_app_context(app_context), provide_container(self.container):
|
|
23
26
|
yield None
|
|
@@ -49,18 +52,20 @@ class UnitOfWorkContextProvider:
|
|
|
49
52
|
return interceptors
|
|
50
53
|
|
|
51
54
|
@asynccontextmanager
|
|
52
|
-
async def __call__(
|
|
55
|
+
async def __call__(
|
|
56
|
+
self, app_context: AppTransactionContext
|
|
57
|
+
) -> AsyncGenerator[None, None]:
|
|
53
58
|
|
|
54
59
|
app_interceptors = self.factory_app_interceptors()
|
|
60
|
+
with provide_metadata(app_context.controller_member_reflect.metadata):
|
|
61
|
+
ctxs = [self.container_interceptor.intercept(app_context)] + [
|
|
62
|
+
interceptor.intercept(app_context) for interceptor in app_interceptors
|
|
63
|
+
]
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
]
|
|
65
|
+
for ctx in ctxs:
|
|
66
|
+
await ctx.__aenter__()
|
|
59
67
|
|
|
60
|
-
|
|
61
|
-
await ctx.__aenter__()
|
|
62
|
-
|
|
63
|
-
yield None
|
|
68
|
+
yield None
|
|
64
69
|
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
for ctx in reversed(ctxs):
|
|
71
|
+
await ctx.__aexit__(None, None, None)
|
|
@@ -3,10 +3,14 @@ from dataclasses import dataclass
|
|
|
3
3
|
from typing import Any, Awaitable, Callable, Generic, TypeVar, cast
|
|
4
4
|
|
|
5
5
|
from jararaca.messagebus.message import INHERITS_MESSAGE_CO, Message, MessageOf
|
|
6
|
-
from jararaca.
|
|
6
|
+
from jararaca.reflect.controller_inspect import (
|
|
7
|
+
ControllerMemberReflect,
|
|
8
|
+
inspect_controller,
|
|
9
|
+
)
|
|
10
|
+
from jararaca.scheduler.decorators import ScheduledAction, ScheduledActionData
|
|
7
11
|
|
|
8
12
|
DECORATED_FUNC = TypeVar("DECORATED_FUNC", bound=Callable[..., Any])
|
|
9
|
-
|
|
13
|
+
DECORATED_T = TypeVar("DECORATED_T", bound=Any)
|
|
10
14
|
|
|
11
15
|
|
|
12
16
|
class MessageHandler(Generic[INHERITS_MESSAGE_CO]):
|
|
@@ -60,7 +64,8 @@ class MessageHandler(Generic[INHERITS_MESSAGE_CO]):
|
|
|
60
64
|
class MessageHandlerData:
|
|
61
65
|
message_type: type[Any]
|
|
62
66
|
spec: MessageHandler[Message]
|
|
63
|
-
|
|
67
|
+
instance_callable: Callable[[MessageOf[Any]], Awaitable[None]]
|
|
68
|
+
controller_member: ControllerMemberReflect
|
|
64
69
|
|
|
65
70
|
|
|
66
71
|
@dataclass(frozen=True)
|
|
@@ -68,16 +73,9 @@ class ScheduleDispatchData:
|
|
|
68
73
|
timestamp: float
|
|
69
74
|
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
class ScheduledActionData:
|
|
73
|
-
spec: ScheduledAction
|
|
74
|
-
callable: Callable[
|
|
75
|
-
..., Awaitable[None]
|
|
76
|
-
] # Callable[[ScheduleDispatchData], Awaitable[None]]
|
|
77
|
-
|
|
76
|
+
SCHEDULED_ACTION_DATA_SET = set[ScheduledActionData]
|
|
78
77
|
|
|
79
78
|
MESSAGE_HANDLER_DATA_SET = set[MessageHandlerData]
|
|
80
|
-
SCHEDULED_ACTION_DATA_SET = set[ScheduledActionData]
|
|
81
79
|
|
|
82
80
|
|
|
83
81
|
class MessageBusController:
|
|
@@ -93,55 +91,60 @@ class MessageBusController:
|
|
|
93
91
|
def get_messagebus_factory(
|
|
94
92
|
self,
|
|
95
93
|
) -> Callable[
|
|
96
|
-
[
|
|
94
|
+
[DECORATED_T], tuple[MESSAGE_HANDLER_DATA_SET, SCHEDULED_ACTION_DATA_SET]
|
|
97
95
|
]:
|
|
98
96
|
if self.messagebus_factory is None:
|
|
99
97
|
raise Exception("MessageBus factory is not set")
|
|
100
98
|
return self.messagebus_factory
|
|
101
99
|
|
|
102
|
-
def __call__(self,
|
|
100
|
+
def __call__(self, cls_t: type[DECORATED_T]) -> type[DECORATED_T]:
|
|
103
101
|
|
|
104
102
|
def messagebus_factory(
|
|
105
|
-
instance:
|
|
103
|
+
instance: DECORATED_T,
|
|
106
104
|
) -> tuple[MESSAGE_HANDLER_DATA_SET, SCHEDULED_ACTION_DATA_SET]:
|
|
107
105
|
handlers: MESSAGE_HANDLER_DATA_SET = set()
|
|
108
106
|
|
|
109
107
|
schedulers: SCHEDULED_ACTION_DATA_SET = set()
|
|
110
108
|
|
|
111
|
-
members =
|
|
109
|
+
controller, members = inspect_controller(cls_t)
|
|
112
110
|
|
|
113
|
-
for name, member in members:
|
|
114
|
-
message_handler_decoration = MessageHandler.get_message_incoming(
|
|
111
|
+
for name, member in members.items():
|
|
112
|
+
message_handler_decoration = MessageHandler.get_message_incoming(
|
|
113
|
+
member.member_function
|
|
114
|
+
)
|
|
115
115
|
scheduled_action_decoration = ScheduledAction.get_scheduled_action(
|
|
116
|
-
member
|
|
116
|
+
member.member_function
|
|
117
117
|
)
|
|
118
118
|
|
|
119
119
|
if message_handler_decoration is not None:
|
|
120
120
|
|
|
121
|
-
if not inspect.iscoroutinefunction(member):
|
|
121
|
+
if not inspect.iscoroutinefunction(member.member_function):
|
|
122
122
|
raise Exception(
|
|
123
123
|
"Message incoming handler '%s' from '%s.%s' must be a coroutine function"
|
|
124
|
-
% (name,
|
|
124
|
+
% (name, cls_t.__module__, cls_t.__qualname__)
|
|
125
125
|
)
|
|
126
126
|
|
|
127
127
|
handlers.add(
|
|
128
128
|
MessageHandlerData(
|
|
129
129
|
message_type=message_handler_decoration.message_type,
|
|
130
130
|
spec=message_handler_decoration,
|
|
131
|
-
|
|
131
|
+
instance_callable=getattr(instance, name),
|
|
132
|
+
controller_member=member,
|
|
132
133
|
)
|
|
133
134
|
)
|
|
134
135
|
elif scheduled_action_decoration is not None:
|
|
135
|
-
if not inspect.iscoroutinefunction(member):
|
|
136
|
+
if not inspect.iscoroutinefunction(member.member_function):
|
|
136
137
|
raise Exception(
|
|
137
138
|
"Scheduled action handler '%s' from '%s.%s' must be a coroutine function"
|
|
138
|
-
% (name,
|
|
139
|
+
% (name, cls_t.__module__, cls_t.__qualname__)
|
|
139
140
|
)
|
|
141
|
+
instance_callable = getattr(instance, name)
|
|
140
142
|
|
|
141
143
|
schedulers.add(
|
|
142
144
|
ScheduledActionData(
|
|
145
|
+
controller_member=member,
|
|
143
146
|
spec=scheduled_action_decoration,
|
|
144
|
-
callable=
|
|
147
|
+
callable=instance_callable,
|
|
145
148
|
)
|
|
146
149
|
)
|
|
147
150
|
|
|
@@ -149,19 +152,17 @@ class MessageBusController:
|
|
|
149
152
|
|
|
150
153
|
self.messagebus_factory = messagebus_factory
|
|
151
154
|
|
|
152
|
-
MessageBusController.register(
|
|
155
|
+
MessageBusController.register(cls_t, self)
|
|
153
156
|
|
|
154
|
-
return
|
|
157
|
+
return cls_t
|
|
155
158
|
|
|
156
159
|
@staticmethod
|
|
157
|
-
def register(
|
|
158
|
-
func: type[DECORATED_CLASS], messagebus: "MessageBusController"
|
|
159
|
-
) -> None:
|
|
160
|
+
def register(func: type[DECORATED_T], messagebus: "MessageBusController") -> None:
|
|
160
161
|
|
|
161
162
|
setattr(func, MessageBusController.MESSAGEBUS_ATTR, messagebus)
|
|
162
163
|
|
|
163
164
|
@staticmethod
|
|
164
|
-
def get_messagebus(func: type[
|
|
165
|
+
def get_messagebus(func: type[DECORATED_T]) -> "MessageBusController | None":
|
|
165
166
|
if not hasattr(func, MessageBusController.MESSAGEBUS_ATTR):
|
|
166
167
|
return None
|
|
167
168
|
|
|
@@ -3,7 +3,7 @@ from typing import AsyncContextManager, AsyncGenerator, Protocol
|
|
|
3
3
|
|
|
4
4
|
from jararaca.broker_backend import MessageBrokerBackend
|
|
5
5
|
from jararaca.messagebus.publisher import MessagePublisher, provide_message_publisher
|
|
6
|
-
from jararaca.microservice import
|
|
6
|
+
from jararaca.microservice import AppInterceptor, AppTransactionContext
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class MessageBusConnectionFactory(Protocol):
|
|
@@ -24,8 +24,10 @@ class MessageBusPublisherInterceptor(AppInterceptor):
|
|
|
24
24
|
self.message_scheduler = message_scheduler
|
|
25
25
|
|
|
26
26
|
@asynccontextmanager
|
|
27
|
-
async def intercept(
|
|
28
|
-
|
|
27
|
+
async def intercept(
|
|
28
|
+
self, app_context: AppTransactionContext
|
|
29
|
+
) -> AsyncGenerator[None, None]:
|
|
30
|
+
if app_context.transaction_data.context_type == "websocket":
|
|
29
31
|
yield
|
|
30
32
|
return
|
|
31
33
|
|
jararaca/messagebus/worker.py
CHANGED
|
@@ -25,7 +25,11 @@ from jararaca.messagebus.decorators import (
|
|
|
25
25
|
MessageHandlerData,
|
|
26
26
|
)
|
|
27
27
|
from jararaca.messagebus.message import Message, MessageOf
|
|
28
|
-
from jararaca.microservice import
|
|
28
|
+
from jararaca.microservice import (
|
|
29
|
+
AppTransactionContext,
|
|
30
|
+
MessageBusTransactionData,
|
|
31
|
+
Microservice,
|
|
32
|
+
)
|
|
29
33
|
from jararaca.utils.rabbitmq_utils import RabbitmqUtils
|
|
30
34
|
|
|
31
35
|
logger = logging.getLogger(__name__)
|
|
@@ -109,7 +113,7 @@ class AioPikaMicroserviceConsumer:
|
|
|
109
113
|
|
|
110
114
|
for handler in self.message_handler_set:
|
|
111
115
|
|
|
112
|
-
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.
|
|
116
|
+
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.instance_callable.__module__}.{handler.instance_callable.__qualname__}"
|
|
113
117
|
routing_key = f"{handler.message_type.MESSAGE_TOPIC}.#"
|
|
114
118
|
|
|
115
119
|
self.incoming_map[queue_name] = handler
|
|
@@ -219,7 +223,7 @@ class MessageHandlerCallback:
|
|
|
219
223
|
|
|
220
224
|
return
|
|
221
225
|
|
|
222
|
-
handler = handler_data.
|
|
226
|
+
handler = handler_data.instance_callable
|
|
223
227
|
|
|
224
228
|
sig = inspect.signature(handler)
|
|
225
229
|
|
|
@@ -263,9 +267,12 @@ class MessageHandlerCallback:
|
|
|
263
267
|
assert incoming_message_spec is not None
|
|
264
268
|
|
|
265
269
|
async with self.consumer.uow_context_provider(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
270
|
+
AppTransactionContext(
|
|
271
|
+
controller_member_reflect=handler_data.controller_member,
|
|
272
|
+
transaction_data=MessageBusTransactionData(
|
|
273
|
+
message=builded_message,
|
|
274
|
+
topic=routing_key,
|
|
275
|
+
),
|
|
269
276
|
)
|
|
270
277
|
):
|
|
271
278
|
ctx: AsyncContextManager[Any]
|
jararaca/messagebus/worker_v2.py
CHANGED
|
@@ -6,15 +6,7 @@ from abc import ABC
|
|
|
6
6
|
from contextlib import asynccontextmanager, suppress
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
from datetime import UTC, datetime
|
|
9
|
-
from typing import
|
|
10
|
-
Any,
|
|
11
|
-
AsyncContextManager,
|
|
12
|
-
AsyncGenerator,
|
|
13
|
-
Awaitable,
|
|
14
|
-
Callable,
|
|
15
|
-
Type,
|
|
16
|
-
get_origin,
|
|
17
|
-
)
|
|
9
|
+
from typing import Any, AsyncContextManager, AsyncGenerator, Type, get_origin
|
|
18
10
|
from urllib.parse import parse_qs, urlparse
|
|
19
11
|
|
|
20
12
|
import aio_pika
|
|
@@ -37,15 +29,16 @@ from jararaca.messagebus.decorators import (
|
|
|
37
29
|
MessageBusController,
|
|
38
30
|
MessageHandler,
|
|
39
31
|
MessageHandlerData,
|
|
40
|
-
ScheduledActionData,
|
|
41
32
|
ScheduleDispatchData,
|
|
42
33
|
)
|
|
43
34
|
from jararaca.messagebus.message import Message, MessageOf
|
|
44
35
|
from jararaca.microservice import (
|
|
45
|
-
|
|
36
|
+
AppTransactionContext,
|
|
37
|
+
MessageBusTransactionData,
|
|
46
38
|
Microservice,
|
|
47
|
-
|
|
39
|
+
SchedulerTransactionData,
|
|
48
40
|
)
|
|
41
|
+
from jararaca.scheduler.decorators import ScheduledActionData
|
|
49
42
|
from jararaca.utils.rabbitmq_utils import RabbitmqUtils
|
|
50
43
|
|
|
51
44
|
logger = logging.getLogger(__name__)
|
|
@@ -152,7 +145,7 @@ class AioPikaMicroserviceConsumer(MessageBusConsumer):
|
|
|
152
145
|
|
|
153
146
|
for handler in self.message_handler_set:
|
|
154
147
|
|
|
155
|
-
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.
|
|
148
|
+
queue_name = f"{handler.message_type.MESSAGE_TOPIC}.{handler.instance_callable.__module__}.{handler.instance_callable.__qualname__}"
|
|
156
149
|
routing_key = f"{handler.message_type.MESSAGE_TOPIC}.#"
|
|
157
150
|
|
|
158
151
|
self.incoming_map[queue_name] = handler
|
|
@@ -311,7 +304,6 @@ class ScheduledMessageHandlerCallback:
|
|
|
311
304
|
|
|
312
305
|
task = asyncio.create_task(
|
|
313
306
|
self.run_with_context(
|
|
314
|
-
self.scheduled_action.callable,
|
|
315
307
|
self.scheduled_action,
|
|
316
308
|
(ScheduleDispatchData(int(aio_pika_message.body.decode("utf-8"))),),
|
|
317
309
|
{},
|
|
@@ -321,7 +313,6 @@ class ScheduledMessageHandlerCallback:
|
|
|
321
313
|
elif len(sig.parameters) == 0:
|
|
322
314
|
task = asyncio.create_task(
|
|
323
315
|
self.run_with_context(
|
|
324
|
-
self.scheduled_action.callable,
|
|
325
316
|
self.scheduled_action,
|
|
326
317
|
(),
|
|
327
318
|
{},
|
|
@@ -347,21 +338,22 @@ class ScheduledMessageHandlerCallback:
|
|
|
347
338
|
|
|
348
339
|
async def run_with_context(
|
|
349
340
|
self,
|
|
350
|
-
func: Callable[..., Awaitable[None]],
|
|
351
341
|
scheduled_action: ScheduledActionData,
|
|
352
342
|
args: tuple[Any, ...],
|
|
353
343
|
kwargs: dict[str, Any],
|
|
354
344
|
) -> None:
|
|
355
345
|
async with self.consumer.uow_context_provider(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
346
|
+
AppTransactionContext(
|
|
347
|
+
controller_member_reflect=scheduled_action.controller_member,
|
|
348
|
+
transaction_data=SchedulerTransactionData(
|
|
349
|
+
scheduled_to=datetime.now(UTC),
|
|
350
|
+
cron_expression=scheduled_action.spec.cron,
|
|
351
|
+
triggered_at=datetime.now(UTC),
|
|
352
|
+
),
|
|
361
353
|
)
|
|
362
354
|
):
|
|
363
355
|
|
|
364
|
-
await
|
|
356
|
+
await scheduled_action.callable(*args, **kwargs)
|
|
365
357
|
|
|
366
358
|
|
|
367
359
|
class MessageHandlerCallback:
|
|
@@ -427,7 +419,7 @@ class MessageHandlerCallback:
|
|
|
427
419
|
|
|
428
420
|
handler_data = self.message_handler
|
|
429
421
|
|
|
430
|
-
handler = handler_data.
|
|
422
|
+
handler = handler_data.instance_callable
|
|
431
423
|
|
|
432
424
|
sig = inspect.signature(handler)
|
|
433
425
|
|
|
@@ -471,9 +463,12 @@ class MessageHandlerCallback:
|
|
|
471
463
|
assert incoming_message_spec is not None
|
|
472
464
|
|
|
473
465
|
async with self.consumer.uow_context_provider(
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
466
|
+
AppTransactionContext(
|
|
467
|
+
controller_member_reflect=handler_data.controller_member,
|
|
468
|
+
transaction_data=MessageBusTransactionData(
|
|
469
|
+
message=builded_message,
|
|
470
|
+
topic=routing_key,
|
|
471
|
+
),
|
|
477
472
|
)
|
|
478
473
|
):
|
|
479
474
|
ctx: AsyncContextManager[Any]
|