dbos 1.3.0a9__py3-none-any.whl → 1.4.0__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/_event_loop.py CHANGED
@@ -7,9 +7,13 @@ class BackgroundEventLoop:
7
7
  """
8
8
  This is the event loop to which DBOS submits any coroutines that are not started from within an event loop.
9
9
  In particular, coroutines submitted to queues (such as from scheduled workflows) run on this event loop.
10
+
11
+ If a main event loop is known (whether because an event loop existed in the thread that called DBOS.launch
12
+ or because a FastAPI event loop was detected) then coroutines are submitted there instead.
10
13
  """
11
14
 
12
15
  def __init__(self) -> None:
16
+ self._main_loop: Optional[asyncio.AbstractEventLoop] = None
13
17
  self._loop: Optional[asyncio.AbstractEventLoop] = None
14
18
  self._thread: Optional[threading.Thread] = None
15
19
  self._running = False
@@ -19,6 +23,7 @@ class BackgroundEventLoop:
19
23
  if self._running:
20
24
  return
21
25
 
26
+ self.set_main_loop()
22
27
  self._thread = threading.Thread(target=self._run_event_loop, daemon=True)
23
28
  self._thread.start()
24
29
  self._ready.wait() # Wait until the loop is running
@@ -58,10 +63,23 @@ class BackgroundEventLoop:
58
63
  await asyncio.gather(*tasks, return_exceptions=True)
59
64
  self._loop.stop()
60
65
 
66
+ def set_main_loop(self) -> None:
67
+ """
68
+ Set the main loop to the currently running event loop.
69
+ Should be called from the main thread.
70
+ """
71
+ try:
72
+ self._main_loop = asyncio.get_running_loop()
73
+ except:
74
+ # There's no running event loop to set
75
+ pass
76
+
61
77
  T = TypeVar("T")
62
78
 
63
79
  def submit_coroutine(self, coro: Coroutine[Any, Any, T]) -> T:
64
80
  """Submit a coroutine to the background event loop"""
81
+ if self._main_loop is not None and self._main_loop.is_running():
82
+ return asyncio.run_coroutine_threadsafe(coro, self._main_loop).result()
65
83
  if self._loop is None:
66
84
  raise RuntimeError("Event loop not started")
67
85
  return asyncio.run_coroutine_threadsafe(coro, self._loop).result()
dbos/_fastapi.py CHANGED
@@ -44,11 +44,10 @@ class LifespanMiddleware:
44
44
  if scope["type"] == "lifespan":
45
45
 
46
46
  async def wrapped_send(message: MutableMapping[str, Any]) -> None:
47
- if (
48
- message["type"] == "lifespan.startup.complete"
49
- and not self.dbos._launched
50
- ):
51
- self.dbos._launch()
47
+ if message["type"] == "lifespan.startup.complete":
48
+ self.dbos._background_event_loop.set_main_loop()
49
+ if not self.dbos._launched:
50
+ self.dbos._launch()
52
51
  elif message["type"] == "lifespan.shutdown.complete":
53
52
  self.dbos._destroy()
54
53
  await send(message)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 1.3.0a9
3
+ Version: 1.4.0
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-1.3.0a9.dist-info/METADATA,sha256=jFue4-stUb4XRh7IGeKJRNFTeBdmJdHojTq06F-2tgg,13267
2
- dbos-1.3.0a9.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
- dbos-1.3.0a9.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
- dbos-1.3.0a9.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
1
+ dbos-1.4.0.dist-info/METADATA,sha256=t968t9UonOSWFDSSmhCujgbvRr_dn1yyVXoJPI31d6U,13265
2
+ dbos-1.4.0.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
+ dbos-1.4.0.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
+ dbos-1.4.0.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
5
5
  dbos/__init__.py,sha256=NssPCubaBxdiKarOWa-wViz1hdJSkmBGcpLX_gQ4NeA,891
6
6
  dbos/__main__.py,sha256=G7Exn-MhGrVJVDbgNlpzhfh8WMX_72t3_oJaFT9Lmt8,653
7
7
  dbos/_admin_server.py,sha256=TWXi4drrzKFpKkUmEJpJkQBZxAtOalnhtYicEn2nDK0,10618
@@ -18,8 +18,8 @@ dbos/_dbos_config.py,sha256=2CC1YR8lP9W-_NsMUMnTnW-v-70KN4XkbJEeNJ78RlQ,20373
18
18
  dbos/_debug.py,sha256=MNlQVZ6TscGCRQeEEL0VE8Uignvr6dPeDDDefS3xgIE,1823
19
19
  dbos/_docker_pg_helper.py,sha256=tLJXWqZ4S-ExcaPnxg_i6cVxL6ZxrYlZjaGsklY-s2I,6115
20
20
  dbos/_error.py,sha256=q0OQJZTbR8FFHV9hEpAGpz9oWBT5L509zUhmyff7FJw,8500
21
- dbos/_event_loop.py,sha256=NmaLbEQFfEK36S_0KhVD39YdYrGce3qSKCTJ-5RqKQ0,2136
22
- dbos/_fastapi.py,sha256=m4SL3H9P-NBQ_ZrbFxAWMOqNyIi3HGEn2ODR7xAK038,3118
21
+ dbos/_event_loop.py,sha256=cvaFN9-II3MsHEOq8QoICc_8qSKrjikMlLfuhC3Y8Dk,2923
22
+ dbos/_fastapi.py,sha256=T7YlVY77ASqyTqq0aAPclZ9YzlXdGTT0lEYSwSgt1EE,3151
23
23
  dbos/_flask.py,sha256=Npnakt-a3W5OykONFRkDRnumaDhTQmA0NPdUCGRYKXE,1652
24
24
  dbos/_kafka.py,sha256=pz0xZ9F3X9Ky1k-VSbeF3tfPhP3UPr3lUUhUfE41__U,4198
25
25
  dbos/_kafka_message.py,sha256=NYvOXNG3Qn7bghn1pv3fg4Pbs86ILZGcK4IB-MLUNu0,409
@@ -69,4 +69,4 @@ dbos/cli/cli.py,sha256=EemOMqNpzSU2BQhAxV_e59pBRITDLwt49HF6W3uWBZg,20775
69
69
  dbos/dbos-config.schema.json,sha256=CjaspeYmOkx6Ip_pcxtmfXJTn_YGdSx_0pcPBF7KZmo,6060
70
70
  dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
71
71
  version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
72
- dbos-1.3.0a9.dist-info/RECORD,,
72
+ dbos-1.4.0.dist-info/RECORD,,
File without changes