arpakitlib 1.7.93__py3-none-any.whl → 1.7.94__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.
- arpakitlib/ar_base_worker_util.py +34 -14
- arpakitlib/ar_operation_execution_util.py +27 -19
- {arpakitlib-1.7.93.dist-info → arpakitlib-1.7.94.dist-info}/METADATA +1 -1
- {arpakitlib-1.7.93.dist-info → arpakitlib-1.7.94.dist-info}/RECORD +8 -8
- {arpakitlib-1.7.93.dist-info → arpakitlib-1.7.94.dist-info}/LICENSE +0 -0
- {arpakitlib-1.7.93.dist-info → arpakitlib-1.7.94.dist-info}/NOTICE +0 -0
- {arpakitlib-1.7.93.dist-info → arpakitlib-1.7.94.dist-info}/WHEEL +0 -0
- {arpakitlib-1.7.93.dist-info → arpakitlib-1.7.94.dist-info}/entry_points.txt +0 -0
@@ -6,11 +6,14 @@ import multiprocessing
|
|
6
6
|
import threading
|
7
7
|
from abc import ABC
|
8
8
|
from datetime import timedelta
|
9
|
+
from random import randint
|
9
10
|
from typing import Any
|
11
|
+
from uuid import uuid4
|
10
12
|
|
13
|
+
from arpakitlib.ar_datetime_util import now_utc_dt
|
11
14
|
from arpakitlib.ar_enumeration_util import Enumeration
|
12
15
|
from arpakitlib.ar_func_util import is_async_function, is_sync_function
|
13
|
-
from arpakitlib.ar_sleep_util import sync_safe_sleep
|
16
|
+
from arpakitlib.ar_sleep_util import sync_safe_sleep
|
14
17
|
|
15
18
|
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
16
19
|
|
@@ -21,15 +24,23 @@ class BaseWorker(ABC):
|
|
21
24
|
*,
|
22
25
|
timeout_after_run=timedelta(seconds=0.3),
|
23
26
|
timeout_after_err_in_run=timedelta(seconds=1),
|
24
|
-
startup_funcs: list[Any] | None = None
|
27
|
+
startup_funcs: list[Any] | None = None,
|
28
|
+
worker_name: str | None = None
|
25
29
|
):
|
26
30
|
if startup_funcs is None:
|
27
31
|
startup_funcs = []
|
28
32
|
self.startup_funcs = startup_funcs
|
29
|
-
|
30
|
-
|
31
|
-
self.
|
32
|
-
self.
|
33
|
+
if worker_name is None:
|
34
|
+
worker_name = self.__class__.__name__
|
35
|
+
self.worker_name = worker_name
|
36
|
+
self.worker_creation_dt = now_utc_dt()
|
37
|
+
self.worker_id = f"{str(uuid4()).replace(' - ', '')}_{randint(1000, 9999)}"
|
38
|
+
self.worker_fullname = (
|
39
|
+
f"{self.worker_name}_{self.worker_creation_dt.isoformat()}_{self.worker_id}"
|
40
|
+
)
|
41
|
+
self._logger = logging.getLogger(self.worker_fullname)
|
42
|
+
self.timeout_after_run = timeout_after_run
|
43
|
+
self.timeout_after_err_in_run = timeout_after_err_in_run
|
33
44
|
|
34
45
|
def sync_run_startup_funcs(self):
|
35
46
|
for startup_func in self.startup_funcs:
|
@@ -41,10 +52,10 @@ class BaseWorker(ABC):
|
|
41
52
|
raise TypeError("no sync and not async")
|
42
53
|
|
43
54
|
def sync_on_startup(self):
|
44
|
-
|
55
|
+
self.sync_run_startup_funcs()
|
45
56
|
|
46
57
|
def sync_run(self):
|
47
|
-
self._logger.info("hello world")
|
58
|
+
self._logger.info(f"hello world, im {self.worker_fullname}")
|
48
59
|
|
49
60
|
def sync_run_on_error(self, exception: BaseException, **kwargs):
|
50
61
|
pass
|
@@ -66,8 +77,8 @@ class BaseWorker(ABC):
|
|
66
77
|
except BaseException as exception_:
|
67
78
|
self._logger.error("error in sync_run_on_error", exc_info=exception_)
|
68
79
|
raise exception_
|
69
|
-
|
70
|
-
|
80
|
+
sync_safe_sleep(self.timeout_after_err_in_run)
|
81
|
+
sync_safe_sleep(self.timeout_after_run)
|
71
82
|
|
72
83
|
async def async_run_startup_funcs(self):
|
73
84
|
for startup_func in self.startup_funcs:
|
@@ -79,10 +90,10 @@ class BaseWorker(ABC):
|
|
79
90
|
raise TypeError("no sync and not async")
|
80
91
|
|
81
92
|
async def async_on_startup(self):
|
82
|
-
|
93
|
+
await self.async_run_startup_funcs()
|
83
94
|
|
84
95
|
async def async_run(self):
|
85
|
-
self._logger.info("hello world")
|
96
|
+
self._logger.info(f"hello world, im {self.worker_fullname}")
|
86
97
|
|
87
98
|
async def async_run_on_error(self, exception: BaseException, **kwargs):
|
88
99
|
pass
|
@@ -104,8 +115,8 @@ class BaseWorker(ABC):
|
|
104
115
|
except BaseException as exception_:
|
105
116
|
self._logger.error("error in async_run_on_error", exc_info=exception_)
|
106
117
|
raise exception_
|
107
|
-
|
108
|
-
|
118
|
+
sync_safe_sleep(self.timeout_after_err_in_run)
|
119
|
+
sync_safe_sleep(self.timeout_after_run)
|
109
120
|
|
110
121
|
|
111
122
|
class SafeRunInBackgroundModes(Enumeration):
|
@@ -136,6 +147,15 @@ def safe_run_worker_in_background(*, worker: BaseWorker, mode: str) -> (
|
|
136
147
|
return res
|
137
148
|
|
138
149
|
|
150
|
+
def safe_run_workers_in_background(
|
151
|
+
*, workers: list[BaseWorker], mode: str
|
152
|
+
) -> list[asyncio.Task] | list[threading.Thread] | list[multiprocessing.Process]:
|
153
|
+
res = []
|
154
|
+
for worker in workers:
|
155
|
+
res.append(safe_run_worker_in_background(worker=worker, mode=mode))
|
156
|
+
return res
|
157
|
+
|
158
|
+
|
139
159
|
def __example():
|
140
160
|
pass
|
141
161
|
|
@@ -148,7 +148,9 @@ class BaseOperationExecutor:
|
|
148
148
|
raise Exception("raise_fake_exception")
|
149
149
|
return operation_dbm
|
150
150
|
|
151
|
-
def sync_safe_execute_operation(
|
151
|
+
def sync_safe_execute_operation(
|
152
|
+
self, operation_dbm: OperationDBM, worker: OperationExecutorWorker
|
153
|
+
) -> OperationDBM:
|
152
154
|
self._logger.info(
|
153
155
|
f"start "
|
154
156
|
f"operation_dbm.id={operation_dbm.id}, "
|
@@ -162,6 +164,12 @@ class BaseOperationExecutor:
|
|
162
164
|
)
|
163
165
|
operation_dbm.execution_start_dt = now_utc_dt()
|
164
166
|
operation_dbm.status = OperationDBM.Statuses.executing
|
167
|
+
operation_dbm.output_data = combine_dicts(
|
168
|
+
operation_dbm.output_data,
|
169
|
+
{
|
170
|
+
worker.worker_fullname: True
|
171
|
+
}
|
172
|
+
)
|
165
173
|
session.commit()
|
166
174
|
session.refresh(operation_dbm)
|
167
175
|
|
@@ -231,7 +239,9 @@ class BaseOperationExecutor:
|
|
231
239
|
raise Exception("raise_fake_exception")
|
232
240
|
return operation_dbm
|
233
241
|
|
234
|
-
async def async_safe_execute_operation(
|
242
|
+
async def async_safe_execute_operation(
|
243
|
+
self, operation_dbm: OperationDBM, worker: OperationExecutorWorker
|
244
|
+
) -> OperationDBM:
|
235
245
|
self._logger.info(
|
236
246
|
f"start "
|
237
247
|
f"operation_dbm.id={operation_dbm.id}, "
|
@@ -245,6 +255,12 @@ class BaseOperationExecutor:
|
|
245
255
|
)
|
246
256
|
operation_dbm.execution_start_dt = now_utc_dt()
|
247
257
|
operation_dbm.status = OperationDBM.Statuses.executing
|
258
|
+
operation_dbm.output_data = combine_dicts(
|
259
|
+
operation_dbm.output_data,
|
260
|
+
{
|
261
|
+
worker.worker_fullname: True
|
262
|
+
}
|
263
|
+
)
|
248
264
|
session.commit()
|
249
265
|
session.refresh(operation_dbm)
|
250
266
|
|
@@ -315,19 +331,15 @@ class OperationExecutorWorker(BaseWorker):
|
|
315
331
|
sqlalchemy_db: SQLAlchemyDB,
|
316
332
|
operation_executor: BaseOperationExecutor | None = None,
|
317
333
|
filter_operation_types: str | list[str] | None = None,
|
318
|
-
timeout_after_run=timedelta(seconds=0.3),
|
319
|
-
timeout_after_err_in_run=timedelta(seconds=1),
|
320
334
|
startup_funcs: list[Any] | None = None
|
321
335
|
):
|
322
|
-
super().__init__(
|
323
|
-
timeout_after_run=timeout_after_run,
|
324
|
-
timeout_after_err_in_run=timeout_after_err_in_run,
|
325
|
-
startup_funcs=startup_funcs
|
326
|
-
)
|
336
|
+
super().__init__(startup_funcs=startup_funcs)
|
327
337
|
self.sqlalchemy_db = sqlalchemy_db
|
328
338
|
if operation_executor is None:
|
329
339
|
operation_executor = BaseOperationExecutor(sqlalchemy_db=sqlalchemy_db)
|
330
340
|
self.operation_executor = operation_executor
|
341
|
+
if isinstance(filter_operation_types, str):
|
342
|
+
filter_operation_types = [filter_operation_types]
|
331
343
|
self.filter_operation_types = filter_operation_types
|
332
344
|
|
333
345
|
def sync_on_startup(self):
|
@@ -335,7 +347,7 @@ class OperationExecutorWorker(BaseWorker):
|
|
335
347
|
self.sync_run_startup_funcs()
|
336
348
|
|
337
349
|
def sync_execute_operation(self, operation_dbm: OperationDBM) -> OperationDBM:
|
338
|
-
return self.operation_executor.sync_safe_execute_operation(operation_dbm=operation_dbm)
|
350
|
+
return self.operation_executor.sync_safe_execute_operation(operation_dbm=operation_dbm, worker=self)
|
339
351
|
|
340
352
|
def sync_run(self):
|
341
353
|
operation_dbm: OperationDBM | None = get_operation_for_execution(
|
@@ -354,7 +366,7 @@ class OperationExecutorWorker(BaseWorker):
|
|
354
366
|
await self.async_run_startup_funcs()
|
355
367
|
|
356
368
|
async def async_execute_operation(self, operation_dbm: OperationDBM) -> OperationDBM:
|
357
|
-
return await self.operation_executor.async_safe_execute_operation(operation_dbm=operation_dbm)
|
369
|
+
return await self.operation_executor.async_safe_execute_operation(operation_dbm=operation_dbm, worker=self)
|
358
370
|
|
359
371
|
async def async_run(self):
|
360
372
|
operation_dbm: OperationDBM | None = get_operation_for_execution(
|
@@ -383,19 +395,15 @@ class ScheduledOperationCreatorWorker(BaseWorker):
|
|
383
395
|
self,
|
384
396
|
*,
|
385
397
|
sqlalchemy_db: SQLAlchemyDB,
|
386
|
-
scheduled_operations: list[ScheduledOperation] | None = None,
|
387
|
-
timeout_after_run=timedelta(seconds=0.3),
|
388
|
-
timeout_after_err_in_run=timedelta(seconds=1),
|
398
|
+
scheduled_operations: ScheduledOperation | list[ScheduledOperation] | None = None,
|
389
399
|
startup_funcs: list[Any] | None = None
|
390
400
|
):
|
391
|
-
super().__init__(
|
392
|
-
timeout_after_run=timeout_after_run,
|
393
|
-
timeout_after_err_in_run=timeout_after_err_in_run,
|
394
|
-
startup_funcs=startup_funcs
|
395
|
-
)
|
401
|
+
super().__init__(startup_funcs=startup_funcs)
|
396
402
|
self.sqlalchemy_db = sqlalchemy_db
|
397
403
|
if scheduled_operations is None:
|
398
404
|
scheduled_operations = []
|
405
|
+
if isinstance(scheduled_operations, ScheduledOperation):
|
406
|
+
scheduled_operations = [scheduled_operations]
|
399
407
|
self.scheduled_operations = scheduled_operations
|
400
408
|
|
401
409
|
def sync_on_startup(self):
|
@@ -120,7 +120,7 @@ arpakitlib/ar_arpakit_project_template_util.py,sha256=AswzQvvb-zfUyrcP4EP0K756YL
|
|
120
120
|
arpakitlib/ar_arpakit_schedule_uust_api_client_util.py,sha256=jGbP6egs2yhgfheyqhM0J-SeM2qp2YrW7dV-u9djv4Q,19223
|
121
121
|
arpakitlib/ar_arpakitlib_cli_util.py,sha256=8lhEDxnwMSRX2PGV2xQtQru1AYKSA92SVolol5u7iBk,3154
|
122
122
|
arpakitlib/ar_base64_util.py,sha256=aZkg2cZTuAaP2IWeG_LXJ6RO7qhyskVwec-Lks0iM-k,676
|
123
|
-
arpakitlib/ar_base_worker_util.py,sha256=
|
123
|
+
arpakitlib/ar_base_worker_util.py,sha256=hV_bMfkO897s00VGMAQ-z8GFzq-vEcRW5TKcmeBhbYM,5667
|
124
124
|
arpakitlib/ar_cache_file_util.py,sha256=Fo2pH-Zqm966KWFBHG_pbiySGZvhIFCYqy7k1weRfJ0,3476
|
125
125
|
arpakitlib/ar_datetime_util.py,sha256=Xe1NiT9oPQzNSG7RVRkhukhbg4i-hhS5ImmV7sPUc8o,971
|
126
126
|
arpakitlib/ar_dict_util.py,sha256=cF5LQJ6tLqyGoEXfDljMDZrikeZoWPw7CgINHIFGvXM,419
|
@@ -164,7 +164,7 @@ arpakitlib/ar_logging_util.py,sha256=mx3H6CzX9dsh29ruFmYnva8lL6mwvdBXmeHH9E2tvu8
|
|
164
164
|
arpakitlib/ar_mongodb_util.py,sha256=2ECkTnGAZ92qxioL-fmN6R4yZOSr3bXdXLWTzT1C3vk,4038
|
165
165
|
arpakitlib/ar_need_type_util.py,sha256=GETiREPMEYhch-yU6T--Bdawlbb04Jp1Qy7cOsUlIeA,2228
|
166
166
|
arpakitlib/ar_openai_api_client_util.py,sha256=_XmlApvHFMSyjvZydPa_kASIt9LsFrZmSC7YEzIG8Bg,1806
|
167
|
-
arpakitlib/ar_operation_execution_util.py,sha256=
|
167
|
+
arpakitlib/ar_operation_execution_util.py,sha256=IxHn-Kv5W5BE-MK7Ok7SEiBaV3UEZK-dyS4HcBiKx2Y,18528
|
168
168
|
arpakitlib/ar_parse_command.py,sha256=-s61xcATIsfw1eV_iD3xi-grsitbGzSDoAFc5V0OFy4,3447
|
169
169
|
arpakitlib/ar_postgresql_util.py,sha256=1AuLjEaa1Lg4pzn-ukCVnDi35Eg1k91APRTqZhIJAdo,945
|
170
170
|
arpakitlib/ar_run_cmd_util.py,sha256=D_rPavKMmWkQtwvZFz-Io5Ak8eSODHkcFeLPzNVC68g,1072
|
@@ -178,9 +178,9 @@ arpakitlib/ar_str_util.py,sha256=tFoGSDYoGpfdVHWor5Li9pEOFmDFlHkX-Z8iOy1LK7Y,353
|
|
178
178
|
arpakitlib/ar_type_util.py,sha256=s0NsTM7mV3HuwyRwyYLdNn7Ep2HbyI4FIr-dd8x0lfI,3734
|
179
179
|
arpakitlib/ar_yookassa_api_client_util.py,sha256=sh4fcUkAkdOetFn9JYoTvjcSXP-M1wU04KEY-ECLfLg,5137
|
180
180
|
arpakitlib/ar_zabbix_api_client_util.py,sha256=Q-VR4MvoZ9aHwZeYZr9G3LwN-ANx1T5KFmF6pvPM-9M,6402
|
181
|
-
arpakitlib-1.7.
|
182
|
-
arpakitlib-1.7.
|
183
|
-
arpakitlib-1.7.
|
184
|
-
arpakitlib-1.7.
|
185
|
-
arpakitlib-1.7.
|
186
|
-
arpakitlib-1.7.
|
181
|
+
arpakitlib-1.7.94.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
|
182
|
+
arpakitlib-1.7.94.dist-info/METADATA,sha256=NgOHw48sxSmfiHkvGRrQbEtwEHA-zJakMbaeet98Wko,2824
|
183
|
+
arpakitlib-1.7.94.dist-info/NOTICE,sha256=95aUzaPJjVpDsGAsNzVnq7tHTxAl0s5UFznCTkVCau4,763
|
184
|
+
arpakitlib-1.7.94.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
185
|
+
arpakitlib-1.7.94.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
|
186
|
+
arpakitlib-1.7.94.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|