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 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 as e:
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
- nextExecTime = iter.get_next(datetime)
32
- sleepTime = nextExecTime - datetime.now(timezone.utc)
33
- if stop_event.wait(timeout=sleepTime.total_seconds()):
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
- with SetWorkflowID(
37
- f"sched-{get_dbos_func_name(func)}-{nextExecTime.isoformat()}"
38
- ):
39
- scheduler_queue.enqueue(func, nextExecTime, datetime.now(timezone.utc))
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 as e:
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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 2.1.0a2
3
+ Version: 2.1.0a3
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
- dbos-2.1.0a2.dist-info/METADATA,sha256=cjLi7rpM1wJUcKQxa6jFruCxYOhGVfEmGCogTXEa7HA,14532
2
- dbos-2.1.0a2.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- dbos-2.1.0a2.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
- dbos-2.1.0a2.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
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=CWeGVfl9h51VXfxt80y5Da_5pE8SPty_AYkfpJkkMxQ,2117
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.0a2.dist-info/RECORD,,
59
+ dbos-2.1.0a3.dist-info/RECORD,,
File without changes