jararaca 0.3.9__py3-none-any.whl → 0.3.11__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 +76 -5
- jararaca/cli.py +460 -116
- jararaca/core/uow.py +17 -12
- jararaca/messagebus/decorators.py +33 -30
- jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py +30 -2
- jararaca/messagebus/interceptors/publisher_interceptor.py +7 -3
- jararaca/messagebus/publisher.py +14 -6
- jararaca/messagebus/worker.py +1102 -88
- jararaca/microservice.py +137 -34
- 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/persistence/utilities.py +32 -20
- jararaca/presentation/decorators.py +96 -10
- jararaca/presentation/server.py +31 -4
- jararaca/presentation/websocket/context.py +30 -4
- jararaca/presentation/websocket/types.py +2 -2
- jararaca/presentation/websocket/websocket_interceptor.py +28 -4
- jararaca/reflect/__init__.py +0 -0
- jararaca/reflect/controller_inspect.py +75 -0
- jararaca/{tools → reflect}/metadata.py +25 -5
- jararaca/scheduler/{scheduler_v2.py → beat_worker.py} +49 -53
- jararaca/scheduler/decorators.py +55 -20
- jararaca/tools/app_config/interceptor.py +4 -2
- jararaca/utils/rabbitmq_utils.py +259 -5
- jararaca/utils/retry.py +141 -0
- {jararaca-0.3.9.dist-info → jararaca-0.3.11.dist-info}/METADATA +2 -1
- {jararaca-0.3.9.dist-info → jararaca-0.3.11.dist-info}/RECORD +33 -32
- {jararaca-0.3.9.dist-info → jararaca-0.3.11.dist-info}/WHEEL +1 -1
- jararaca/messagebus/worker_v2.py +0 -617
- jararaca/scheduler/scheduler.py +0 -161
- {jararaca-0.3.9.dist-info → jararaca-0.3.11.dist-info}/LICENSE +0 -0
- {jararaca-0.3.9.dist-info → jararaca-0.3.11.dist-info}/entry_points.txt +0 -0
jararaca/scheduler/scheduler.py
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import inspect
|
|
3
|
-
import logging
|
|
4
|
-
import time
|
|
5
|
-
from contextlib import asynccontextmanager
|
|
6
|
-
from dataclasses import dataclass
|
|
7
|
-
from datetime import UTC, datetime
|
|
8
|
-
from typing import Any, AsyncContextManager, AsyncGenerator, Callable
|
|
9
|
-
|
|
10
|
-
import uvloop
|
|
11
|
-
from croniter import croniter
|
|
12
|
-
|
|
13
|
-
from jararaca.core.uow import UnitOfWorkContextProvider
|
|
14
|
-
from jararaca.di import Container
|
|
15
|
-
from jararaca.lifecycle import AppLifecycle
|
|
16
|
-
from jararaca.messagebus.decorators import ScheduleDispatchData
|
|
17
|
-
from jararaca.microservice import Microservice, SchedulerAppContext
|
|
18
|
-
from jararaca.scheduler.decorators import ScheduledAction
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@dataclass
|
|
24
|
-
class SchedulerConfig:
|
|
25
|
-
interval: int
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def extract_scheduled_actions(
|
|
29
|
-
app: Microservice, container: Container
|
|
30
|
-
) -> list[tuple[Callable[..., Any], "ScheduledAction"]]:
|
|
31
|
-
scheduled_actions: list[tuple[Callable[..., Any], "ScheduledAction"]] = []
|
|
32
|
-
for controllers in app.controllers:
|
|
33
|
-
|
|
34
|
-
controller_instance: Any = container.get_by_type(controllers)
|
|
35
|
-
|
|
36
|
-
controller_scheduled_actions = ScheduledAction.get_type_scheduled_actions(
|
|
37
|
-
controller_instance
|
|
38
|
-
)
|
|
39
|
-
scheduled_actions.extend(controller_scheduled_actions)
|
|
40
|
-
|
|
41
|
-
return scheduled_actions
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# TODO: Implement Backend for Distributed Lock
|
|
45
|
-
# TODO: Improve error handling
|
|
46
|
-
# TODO: Implement logging
|
|
47
|
-
# TODO: Implement tests
|
|
48
|
-
# TODO: Implement graceful shutdown
|
|
49
|
-
# TODO: Implement ScheduletAction parameters configuration
|
|
50
|
-
class Scheduler:
|
|
51
|
-
|
|
52
|
-
def __init__(
|
|
53
|
-
self,
|
|
54
|
-
app: Microservice,
|
|
55
|
-
interval: int,
|
|
56
|
-
) -> None:
|
|
57
|
-
self.app = app
|
|
58
|
-
|
|
59
|
-
self.interval = interval
|
|
60
|
-
self.container = Container(self.app)
|
|
61
|
-
self.uow_provider = UnitOfWorkContextProvider(app, self.container)
|
|
62
|
-
|
|
63
|
-
self.tasks: set[asyncio.Task[Any]] = set()
|
|
64
|
-
self.lock = asyncio.Lock()
|
|
65
|
-
self.shutdown_event = asyncio.Event()
|
|
66
|
-
|
|
67
|
-
self.last_checks: dict[Callable[..., Any], datetime] = {}
|
|
68
|
-
|
|
69
|
-
self.lifceycle = AppLifecycle(app, self.container)
|
|
70
|
-
|
|
71
|
-
async def process_task(
|
|
72
|
-
self, func: Callable[..., Any], scheduled_action: ScheduledAction
|
|
73
|
-
) -> None:
|
|
74
|
-
|
|
75
|
-
async with self.lock:
|
|
76
|
-
task = asyncio.create_task(self.handle_task(func, scheduled_action))
|
|
77
|
-
self.tasks.add(task)
|
|
78
|
-
task.add_done_callback(self.tasks.discard)
|
|
79
|
-
|
|
80
|
-
async def handle_task(
|
|
81
|
-
self, func: Callable[..., Any], scheduled_action: ScheduledAction
|
|
82
|
-
) -> None:
|
|
83
|
-
|
|
84
|
-
last_check = self.last_checks.setdefault(func, datetime.now(UTC))
|
|
85
|
-
|
|
86
|
-
cron = croniter(scheduled_action.cron, last_check)
|
|
87
|
-
next_run: datetime = cron.get_next(datetime)
|
|
88
|
-
if next_run > datetime.now(UTC):
|
|
89
|
-
logger.info(
|
|
90
|
-
f"Skipping {func.__module__}.{func.__qualname__} until {next_run}"
|
|
91
|
-
)
|
|
92
|
-
return
|
|
93
|
-
|
|
94
|
-
logger.info(f"Running {func.__module__}.{func.__qualname__}")
|
|
95
|
-
|
|
96
|
-
action_specs = ScheduledAction.get_scheduled_action(func)
|
|
97
|
-
|
|
98
|
-
assert action_specs is not None
|
|
99
|
-
|
|
100
|
-
ctx: AsyncContextManager[Any]
|
|
101
|
-
if action_specs.timeout:
|
|
102
|
-
ctx = asyncio.timeout(action_specs.timeout)
|
|
103
|
-
else:
|
|
104
|
-
ctx = none_context()
|
|
105
|
-
|
|
106
|
-
try:
|
|
107
|
-
async with self.uow_provider(
|
|
108
|
-
SchedulerAppContext(
|
|
109
|
-
action=func,
|
|
110
|
-
scheduled_to=next_run,
|
|
111
|
-
cron_expression=scheduled_action.cron,
|
|
112
|
-
triggered_at=datetime.now(UTC),
|
|
113
|
-
)
|
|
114
|
-
):
|
|
115
|
-
try:
|
|
116
|
-
async with ctx:
|
|
117
|
-
signature = inspect.signature(func)
|
|
118
|
-
if len(signature.parameters) > 0:
|
|
119
|
-
logging.warning(
|
|
120
|
-
f"Scheduled action {func.__module__}.{func.__qualname__} has parameters, but no arguments were provided. Must be using scheduler-v2"
|
|
121
|
-
)
|
|
122
|
-
await func(ScheduleDispatchData(time.time()))
|
|
123
|
-
else:
|
|
124
|
-
await func()
|
|
125
|
-
|
|
126
|
-
except BaseException as e:
|
|
127
|
-
if action_specs.exception_handler:
|
|
128
|
-
action_specs.exception_handler(e)
|
|
129
|
-
else:
|
|
130
|
-
logging.exception(
|
|
131
|
-
f"Error in scheduled action {scheduled_action}: {e}"
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
except Exception as e:
|
|
135
|
-
logging.exception(f"Error in scheduled action {scheduled_action}: {e}")
|
|
136
|
-
|
|
137
|
-
self.last_checks[func] = datetime.now(UTC)
|
|
138
|
-
|
|
139
|
-
def run(self) -> None:
|
|
140
|
-
|
|
141
|
-
async def run_scheduled_actions() -> None:
|
|
142
|
-
|
|
143
|
-
async with self.lifceycle():
|
|
144
|
-
scheduled_actions = extract_scheduled_actions(self.app, self.container)
|
|
145
|
-
|
|
146
|
-
while True:
|
|
147
|
-
for func, scheduled_action in scheduled_actions:
|
|
148
|
-
if self.shutdown_event.is_set():
|
|
149
|
-
break
|
|
150
|
-
|
|
151
|
-
await self.process_task(func, scheduled_action)
|
|
152
|
-
|
|
153
|
-
await asyncio.sleep(self.interval)
|
|
154
|
-
|
|
155
|
-
with asyncio.Runner(loop_factory=uvloop.new_event_loop) as runner:
|
|
156
|
-
runner.run(run_scheduled_actions())
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@asynccontextmanager
|
|
160
|
-
async def none_context() -> AsyncGenerator[None, None]:
|
|
161
|
-
yield
|
|
File without changes
|
|
File without changes
|