dbos 2.1.0a2__py3-none-any.whl → 2.1.0a3__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.
- dbos/_scheduler.py +24 -14
- {dbos-2.1.0a2.dist-info → dbos-2.1.0a3.dist-info}/METADATA +1 -1
- {dbos-2.1.0a2.dist-info → dbos-2.1.0a3.dist-info}/RECORD +6 -6
- {dbos-2.1.0a2.dist-info → dbos-2.1.0a3.dist-info}/WHEEL +0 -0
- {dbos-2.1.0a2.dist-info → dbos-2.1.0a3.dist-info}/entry_points.txt +0 -0
- {dbos-2.1.0a2.dist-info → dbos-2.1.0a3.dist-info}/licenses/LICENSE +0 -0
dbos/_scheduler.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import random
|
1
2
|
import threading
|
2
3
|
import traceback
|
3
4
|
from datetime import datetime, timezone
|
@@ -15,28 +16,40 @@ from ._registrations import get_dbos_func_name
|
|
15
16
|
|
16
17
|
ScheduledWorkflow = Callable[[datetime, datetime], None]
|
17
18
|
|
18
|
-
scheduler_queue: Queue
|
19
|
-
|
20
19
|
|
21
20
|
def scheduler_loop(
|
22
21
|
func: ScheduledWorkflow, cron: str, stop_event: threading.Event
|
23
22
|
) -> None:
|
23
|
+
from dbos._dbos import _get_dbos_instance
|
24
|
+
|
25
|
+
dbos = _get_dbos_instance()
|
26
|
+
scheduler_queue = dbos._registry.get_internal_queue()
|
24
27
|
try:
|
25
28
|
iter = croniter(cron, datetime.now(timezone.utc), second_at_beginning=True)
|
26
|
-
except Exception
|
29
|
+
except Exception:
|
27
30
|
dbos_logger.error(
|
28
31
|
f'Cannot run scheduled function {get_dbos_func_name(func)}. Invalid crontab "{cron}"'
|
29
32
|
)
|
33
|
+
raise
|
30
34
|
while not stop_event.is_set():
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
next_exec_time = iter.get_next(datetime)
|
36
|
+
sleep_time = (next_exec_time - datetime.now(timezone.utc)).total_seconds()
|
37
|
+
sleep_time = max(0, sleep_time)
|
38
|
+
# To prevent a "thundering herd" problem in a distributed setting,
|
39
|
+
# apply jitter of up to 10% the sleep time, capped at 10 seconds
|
40
|
+
max_jitter = min(sleep_time / 10, 10)
|
41
|
+
jitter = random.uniform(0, max_jitter)
|
42
|
+
if stop_event.wait(timeout=sleep_time + jitter):
|
34
43
|
return
|
35
44
|
try:
|
36
|
-
|
37
|
-
f"sched-{get_dbos_func_name(func)}-{
|
38
|
-
)
|
39
|
-
|
45
|
+
workflowID = (
|
46
|
+
f"sched-{get_dbos_func_name(func)}-{next_exec_time.isoformat()}"
|
47
|
+
)
|
48
|
+
if not dbos._sys_db.get_workflow_status(workflowID):
|
49
|
+
with SetWorkflowID(workflowID):
|
50
|
+
scheduler_queue.enqueue(
|
51
|
+
func, next_exec_time, datetime.now(timezone.utc)
|
52
|
+
)
|
40
53
|
except Exception:
|
41
54
|
dbos_logger.warning(
|
42
55
|
f"Exception encountered in scheduler thread: {traceback.format_exc()})"
|
@@ -49,13 +62,10 @@ def scheduled(
|
|
49
62
|
def decorator(func: ScheduledWorkflow) -> ScheduledWorkflow:
|
50
63
|
try:
|
51
64
|
croniter(cron, datetime.now(timezone.utc), second_at_beginning=True)
|
52
|
-
except Exception
|
65
|
+
except Exception:
|
53
66
|
raise ValueError(
|
54
67
|
f'Invalid crontab "{cron}" for scheduled function function {get_dbos_func_name(func)}.'
|
55
68
|
)
|
56
|
-
|
57
|
-
global scheduler_queue
|
58
|
-
scheduler_queue = dbosreg.get_internal_queue()
|
59
69
|
stop_event = threading.Event()
|
60
70
|
dbosreg.register_poller(stop_event, scheduler_loop, func, cron, stop_event)
|
61
71
|
return func
|
@@ -1,7 +1,7 @@
|
|
1
|
-
dbos-2.1.
|
2
|
-
dbos-2.1.
|
3
|
-
dbos-2.1.
|
4
|
-
dbos-2.1.
|
1
|
+
dbos-2.1.0a3.dist-info/METADATA,sha256=hbeBepjAAjwBEOD2Ew59TtF2J-HeeBzhaMLU5FFPEyg,14532
|
2
|
+
dbos-2.1.0a3.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
|
3
|
+
dbos-2.1.0a3.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
|
4
|
+
dbos-2.1.0a3.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
|
5
5
|
dbos/__init__.py,sha256=pT4BuNLDCrIQX27vQG8NlfxX6PZRU7r9miq4thJTszU,982
|
6
6
|
dbos/__main__.py,sha256=G7Exn-MhGrVJVDbgNlpzhfh8WMX_72t3_oJaFT9Lmt8,653
|
7
7
|
dbos/_admin_server.py,sha256=hubQJw5T8zGKCPNS6FQTXy8jQ8GTJxoYQaDTMlICl9k,16267
|
@@ -31,7 +31,7 @@ dbos/_queue.py,sha256=cgFFwVPUeQtrTgk7ivoTZb0v9ya8rZK4m7-G-h5gIb4,4846
|
|
31
31
|
dbos/_recovery.py,sha256=K-wlFhdf4yGRm6cUzyhcTjQUS0xp2T5rdNMLiiBErYg,2882
|
32
32
|
dbos/_registrations.py,sha256=bEOntObnWaBylnebr5ZpcX2hk7OVLDd1z4BvW4_y3zA,7380
|
33
33
|
dbos/_roles.py,sha256=kCuhhg8XLtrHCgKgm44I0abIRTGHltf88OwjEKAUggk,2317
|
34
|
-
dbos/_scheduler.py,sha256=
|
34
|
+
dbos/_scheduler.py,sha256=n96dNzKMr6-2RQvMxRI6BaoExHbLjw0Kr46j1P-DjP4,2620
|
35
35
|
dbos/_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
36
|
dbos/_schemas/application_database.py,sha256=SypAS9l9EsaBHFn9FR8jmnqt01M74d9AF1AMa4m2hhI,1040
|
37
37
|
dbos/_schemas/system_database.py,sha256=aEkjRQDh9xjdke0d9uFx_20-c9UjQtvuLtHZ24aOypA,5497
|
@@ -56,4 +56,4 @@ dbos/cli/migration.py,sha256=zJnDPUBnil5XZXFxc01EbZ0Radw_y8wtDGZExgelAxc,3633
|
|
56
56
|
dbos/dbos-config.schema.json,sha256=47wofTZ5jlFynec7bG0L369tAXbRQQ2euBxBXvg4m9c,1730
|
57
57
|
dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
|
58
58
|
version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
|
59
|
-
dbos-2.1.
|
59
|
+
dbos-2.1.0a3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|