jararaca 0.3.12a11__tar.gz → 0.3.12a13__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.12a11 → jararaca-0.3.12a13}/PKG-INFO +1 -1
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/pyproject.toml +1 -1
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/websocket/redis.py +113 -7
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/LICENSE +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/README.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/CNAME +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/architecture.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.webp +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/assets/tracing_example.png +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/http-rpc.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/index.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/interceptors.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/messagebus.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/retry.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/scheduler.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/stylesheets/custom.css +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/websocket.md +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/__main__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/broker_backend/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/broker_backend/mapper.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/broker_backend/redis_broker_backend.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/cli.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/common/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/core/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/core/providers.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/core/uow.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/di.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/files/entity.py.mako +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/lifecycle.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/bus_message_controller.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/consumers/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/interceptors/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/interceptors/publisher_interceptor.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/message.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/publisher.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/messagebus/worker.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/microservice.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/observability/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/observability/interceptor.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/observability/providers/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/observability/providers/otel.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/base.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/exports.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/interceptors/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/interceptors/aiosqa_interceptor.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/interceptors/constants.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/interceptors/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/session.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/sort_filter.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/utilities.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/hooks.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/http_microservice.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/server.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/websocket/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/websocket/base_types.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/websocket/context.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/websocket/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/websocket/types.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/presentation/websocket/websocket_interceptor.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/py.typed +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/reflect/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/reflect/controller_inspect.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/reflect/metadata.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/rpc/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/rpc/http/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/rpc/http/backends/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/rpc/http/backends/httpx.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/rpc/http/backends/otel.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/rpc/http/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/rpc/http/httpx.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/scheduler/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/scheduler/beat_worker.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/scheduler/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/scheduler/types.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/tools/app_config/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/tools/app_config/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/tools/app_config/interceptor.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/tools/typescript/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/tools/typescript/decorators.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/tools/typescript/interface_parser.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/utils/__init__.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/utils/rabbitmq_utils.py +0 -0
- {jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/utils/retry.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import logging
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from typing import Any
|
|
4
5
|
|
|
@@ -10,6 +11,8 @@ from jararaca.presentation.websocket.websocket_interceptor import (
|
|
|
10
11
|
WebSocketConnectionBackend,
|
|
11
12
|
)
|
|
12
13
|
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
@dataclass
|
|
15
18
|
class BroadcastMessage:
|
|
@@ -55,6 +58,7 @@ class RedisWebSocketConnectionBackend(WebSocketConnectionBackend):
|
|
|
55
58
|
send_pubsub_channel: str,
|
|
56
59
|
consume_broadcast_timeout: int = 1,
|
|
57
60
|
consume_send_timeout: int = 1,
|
|
61
|
+
retry_delay: float = 5.0,
|
|
58
62
|
) -> None:
|
|
59
63
|
|
|
60
64
|
self.redis = conn
|
|
@@ -66,6 +70,35 @@ class RedisWebSocketConnectionBackend(WebSocketConnectionBackend):
|
|
|
66
70
|
|
|
67
71
|
self.consume_broadcast_timeout = consume_broadcast_timeout
|
|
68
72
|
self.consume_send_timeout = consume_send_timeout
|
|
73
|
+
self.retry_delay = retry_delay
|
|
74
|
+
self.__shutdown_event: asyncio.Event | None = None
|
|
75
|
+
|
|
76
|
+
self.__send_func: SendFunc | None = None
|
|
77
|
+
self.__broadcast_func: BroadcastFunc | None = None
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def shutdown_event(self) -> asyncio.Event:
|
|
81
|
+
if self.__shutdown_event is None:
|
|
82
|
+
raise RuntimeError(
|
|
83
|
+
"Shutdown event is not set. Please configure the backend before using it."
|
|
84
|
+
)
|
|
85
|
+
return self.__shutdown_event
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def send_func(self) -> SendFunc:
|
|
89
|
+
if self.__send_func is None:
|
|
90
|
+
raise RuntimeError(
|
|
91
|
+
"Send function is not set. Please configure the backend before using it."
|
|
92
|
+
)
|
|
93
|
+
return self.__send_func
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def broadcast_func(self) -> BroadcastFunc:
|
|
97
|
+
if self.__broadcast_func is None:
|
|
98
|
+
raise RuntimeError(
|
|
99
|
+
"Broadcast function is not set. Please configure the backend before using it."
|
|
100
|
+
)
|
|
101
|
+
return self.__broadcast_func
|
|
69
102
|
|
|
70
103
|
async def broadcast(self, message: bytes) -> None:
|
|
71
104
|
await self.redis.publish(
|
|
@@ -82,22 +115,95 @@ class RedisWebSocketConnectionBackend(WebSocketConnectionBackend):
|
|
|
82
115
|
def configure(
|
|
83
116
|
self, broadcast: BroadcastFunc, send: SendFunc, shutdown_event: asyncio.Event
|
|
84
117
|
) -> None:
|
|
118
|
+
if self.__shutdown_event is not None:
|
|
119
|
+
raise RuntimeError("Backend is already configured.")
|
|
120
|
+
self.__shutdown_event = shutdown_event
|
|
121
|
+
self.__send_func = send
|
|
122
|
+
self.__broadcast_func = broadcast
|
|
123
|
+
self.setup_send_consumer()
|
|
124
|
+
self.setup_broadcast_consumer()
|
|
85
125
|
|
|
86
|
-
|
|
87
|
-
self.consume_broadcast(broadcast, shutdown_event)
|
|
88
|
-
)
|
|
126
|
+
def setup_send_consumer(self) -> None:
|
|
89
127
|
|
|
90
128
|
send_task = asyncio.get_event_loop().create_task(
|
|
91
|
-
self.consume_send(
|
|
129
|
+
self.consume_send(self.send_func, self.shutdown_event)
|
|
92
130
|
)
|
|
93
131
|
|
|
94
|
-
self.tasks.add(broadcast_task)
|
|
95
132
|
self.tasks.add(send_task)
|
|
133
|
+
send_task.add_done_callback(self.handle_send_task_done)
|
|
134
|
+
|
|
135
|
+
def setup_broadcast_consumer(self) -> None:
|
|
136
|
+
|
|
137
|
+
broadcast_task = asyncio.get_event_loop().create_task(
|
|
138
|
+
self.consume_broadcast(self.broadcast_func, self.shutdown_event)
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
self.tasks.add(broadcast_task)
|
|
142
|
+
|
|
143
|
+
broadcast_task.add_done_callback(self.handle_broadcast_task_done)
|
|
144
|
+
|
|
145
|
+
def handle_broadcast_task_done(self, task: asyncio.Task[Any]) -> None:
|
|
146
|
+
if task.cancelled():
|
|
147
|
+
logger.warning("Broadcast task was cancelled.")
|
|
148
|
+
elif task.exception() is not None:
|
|
149
|
+
logger.exception(
|
|
150
|
+
f"Broadcast task raised an exception:", exc_info=task.exception()
|
|
151
|
+
)
|
|
152
|
+
else:
|
|
153
|
+
logger.warning("Broadcast task somehow completed successfully.")
|
|
154
|
+
|
|
155
|
+
if not self.shutdown_event.is_set():
|
|
156
|
+
logger.warning(
|
|
157
|
+
"Broadcast task completed, but shutdown event is not set. This is unexpected."
|
|
158
|
+
)
|
|
159
|
+
# Add delay before retrying to avoid excessive CPU usage
|
|
160
|
+
asyncio.get_event_loop().create_task(
|
|
161
|
+
self._retry_broadcast_consumer_with_delay()
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def handle_send_task_done(self, task: asyncio.Task[Any]) -> None:
|
|
165
|
+
if task.cancelled():
|
|
166
|
+
logger.warning("Send task was cancelled.")
|
|
167
|
+
elif task.exception() is not None:
|
|
168
|
+
logger.exception(
|
|
169
|
+
f"Send task raised an exception:", exc_info=task.exception()
|
|
170
|
+
)
|
|
171
|
+
else:
|
|
172
|
+
logger.warning("Send task somehow completed successfully.")
|
|
173
|
+
|
|
174
|
+
if not self.shutdown_event.is_set():
|
|
175
|
+
logger.warning(
|
|
176
|
+
"Send task completed, but shutdown event is not set. This is unexpected."
|
|
177
|
+
)
|
|
178
|
+
# Add delay before retrying to avoid excessive CPU usage
|
|
179
|
+
asyncio.get_event_loop().create_task(self._retry_send_consumer_with_delay())
|
|
180
|
+
|
|
181
|
+
async def _retry_broadcast_consumer_with_delay(self) -> None:
|
|
182
|
+
"""Retry setting up broadcast consumer after a delay to avoid excessive CPU usage."""
|
|
183
|
+
logger.info(
|
|
184
|
+
f"Waiting {self.retry_delay} seconds before retrying broadcast consumer..."
|
|
185
|
+
)
|
|
186
|
+
await asyncio.sleep(self.retry_delay)
|
|
187
|
+
|
|
188
|
+
if not self.shutdown_event.is_set():
|
|
189
|
+
logger.info("Retrying broadcast consumer setup...")
|
|
190
|
+
self.setup_broadcast_consumer()
|
|
191
|
+
|
|
192
|
+
async def _retry_send_consumer_with_delay(self) -> None:
|
|
193
|
+
"""Retry setting up send consumer after a delay to avoid excessive CPU usage."""
|
|
194
|
+
logger.info(
|
|
195
|
+
f"Waiting {self.retry_delay} seconds before retrying send consumer..."
|
|
196
|
+
)
|
|
197
|
+
await asyncio.sleep(self.retry_delay)
|
|
198
|
+
|
|
199
|
+
if not self.shutdown_event.is_set():
|
|
200
|
+
logger.info("Retrying send consumer setup...")
|
|
201
|
+
self.setup_send_consumer()
|
|
96
202
|
|
|
97
203
|
async def consume_broadcast(
|
|
98
204
|
self, broadcast: BroadcastFunc, shutdown_event: asyncio.Event
|
|
99
205
|
) -> None:
|
|
100
|
-
|
|
206
|
+
logger.info("Starting broadcast consumer...")
|
|
101
207
|
async with self.redis.pubsub() as pubsub:
|
|
102
208
|
await pubsub.subscribe(self.broadcast_pubsub_channel)
|
|
103
209
|
|
|
@@ -122,7 +228,7 @@ class RedisWebSocketConnectionBackend(WebSocketConnectionBackend):
|
|
|
122
228
|
task.add_done_callback(self.tasks.discard)
|
|
123
229
|
|
|
124
230
|
async def consume_send(self, send: SendFunc, shutdown_event: asyncio.Event) -> None:
|
|
125
|
-
|
|
231
|
+
logger.info("Starting send consumer...")
|
|
126
232
|
async with self.redis.pubsub() as pubsub:
|
|
127
233
|
await pubsub.subscribe(self.send_pubsub_channel)
|
|
128
234
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jararaca-0.3.12a11 → jararaca-0.3.12a13}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg
RENAMED
|
File without changes
|
{jararaca-0.3.12a11 → jararaca-0.3.12a13}/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
|
{jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/broker_backend/redis_broker_backend.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
|
|
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.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/interceptors/constants.py
RENAMED
|
File without changes
|
{jararaca-0.3.12a11 → jararaca-0.3.12a13}/src/jararaca/persistence/interceptors/decorators.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
|
|
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
|