dbos 0.28.0a12__py3-none-any.whl → 0.28.0a14__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/_conductor/conductor.py +32 -1
- dbos/_conductor/protocol.py +19 -2
- dbos/_dbos_config.py +8 -11
- {dbos-0.28.0a12.dist-info → dbos-0.28.0a14.dist-info}/METADATA +1 -1
- {dbos-0.28.0a12.dist-info → dbos-0.28.0a14.dist-info}/RECORD +8 -8
- {dbos-0.28.0a12.dist-info → dbos-0.28.0a14.dist-info}/WHEEL +0 -0
- {dbos-0.28.0a12.dist-info → dbos-0.28.0a14.dist-info}/entry_points.txt +0 -0
- {dbos-0.28.0a12.dist-info → dbos-0.28.0a14.dist-info}/licenses/LICENSE +0 -0
dbos/_conductor/conductor.py
CHANGED
@@ -2,6 +2,7 @@ import socket
|
|
2
2
|
import threading
|
3
3
|
import time
|
4
4
|
import traceback
|
5
|
+
import uuid
|
5
6
|
from importlib.metadata import version
|
6
7
|
from typing import TYPE_CHECKING, Optional
|
7
8
|
|
@@ -9,6 +10,7 @@ from websockets import ConnectionClosed, ConnectionClosedOK, InvalidStatus
|
|
9
10
|
from websockets.sync.client import connect
|
10
11
|
from websockets.sync.connection import Connection
|
11
12
|
|
13
|
+
from dbos._context import SetWorkflowID
|
12
14
|
from dbos._utils import GlobalParams
|
13
15
|
from dbos._workflow_commands import (
|
14
16
|
get_workflow,
|
@@ -168,10 +170,11 @@ class ConductorWebsocket(threading.Thread):
|
|
168
170
|
)
|
169
171
|
websocket.send(resume_response.to_json())
|
170
172
|
elif msg_type == p.MessageType.RESTART:
|
173
|
+
# TODO: deprecate this message type in favor of Fork
|
171
174
|
restart_message = p.RestartRequest.from_json(message)
|
172
175
|
success = True
|
173
176
|
try:
|
174
|
-
self.dbos.
|
177
|
+
self.dbos.fork_workflow(restart_message.workflow_id, 1)
|
175
178
|
except Exception as e:
|
176
179
|
error_message = f"Exception encountered when restarting workflow {restart_message.workflow_id}: {traceback.format_exc()}"
|
177
180
|
self.dbos.logger.error(error_message)
|
@@ -183,6 +186,34 @@ class ConductorWebsocket(threading.Thread):
|
|
183
186
|
error_message=error_message,
|
184
187
|
)
|
185
188
|
websocket.send(restart_response.to_json())
|
189
|
+
elif msg_type == p.MessageType.FORK_WORKFLOW:
|
190
|
+
fork_message = p.ForkWorkflowRequest.from_json(message)
|
191
|
+
new_workflow_id = fork_message.body["new_workflow_id"]
|
192
|
+
if new_workflow_id is None:
|
193
|
+
new_workflow_id = str(uuid.uuid4())
|
194
|
+
workflow_id = fork_message.body["workflow_id"]
|
195
|
+
start_step = fork_message.body["start_step"]
|
196
|
+
app_version = fork_message.body["application_version"]
|
197
|
+
try:
|
198
|
+
with SetWorkflowID(new_workflow_id):
|
199
|
+
new_handle = self.dbos.fork_workflow(
|
200
|
+
workflow_id,
|
201
|
+
start_step,
|
202
|
+
application_version=app_version,
|
203
|
+
)
|
204
|
+
new_workflow_id = new_handle.workflow_id
|
205
|
+
except Exception as e:
|
206
|
+
error_message = f"Exception encountered when forking workflow {workflow_id} to new workflow {new_workflow_id} on step {start_step}, app version {app_version}: {traceback.format_exc()}"
|
207
|
+
self.dbos.logger.error(error_message)
|
208
|
+
new_workflow_id = None
|
209
|
+
|
210
|
+
fork_response = p.ForkWorkflowResponse(
|
211
|
+
type=p.MessageType.FORK_WORKFLOW,
|
212
|
+
request_id=base_message.request_id,
|
213
|
+
new_workflow_id=new_workflow_id,
|
214
|
+
error_message=error_message,
|
215
|
+
)
|
216
|
+
websocket.send(fork_response.to_json())
|
186
217
|
elif msg_type == p.MessageType.LIST_WORKFLOWS:
|
187
218
|
list_workflows_message = p.ListWorkflowsRequest.from_json(
|
188
219
|
message
|
dbos/_conductor/protocol.py
CHANGED
@@ -17,6 +17,7 @@ class MessageType(str, Enum):
|
|
17
17
|
GET_WORKFLOW = "get_workflow"
|
18
18
|
EXIST_PENDING_WORKFLOWS = "exist_pending_workflows"
|
19
19
|
LIST_STEPS = "list_steps"
|
20
|
+
FORK_WORKFLOW = "fork_workflow"
|
20
21
|
|
21
22
|
|
22
23
|
T = TypeVar("T", bound="BaseMessage")
|
@@ -133,7 +134,6 @@ class WorkflowsOutput:
|
|
133
134
|
AuthenticatedRoles: Optional[str]
|
134
135
|
Input: Optional[str]
|
135
136
|
Output: Optional[str]
|
136
|
-
Request: Optional[str]
|
137
137
|
Error: Optional[str]
|
138
138
|
CreatedAt: Optional[str]
|
139
139
|
UpdatedAt: Optional[str]
|
@@ -167,7 +167,6 @@ class WorkflowsOutput:
|
|
167
167
|
AuthenticatedRoles=roles_str,
|
168
168
|
Input=inputs_str,
|
169
169
|
Output=outputs_str,
|
170
|
-
Request=request_str,
|
171
170
|
Error=error_str,
|
172
171
|
CreatedAt=created_at_str,
|
173
172
|
UpdatedAt=updated_at_str,
|
@@ -263,3 +262,21 @@ class ListStepsRequest(BaseMessage):
|
|
263
262
|
class ListStepsResponse(BaseMessage):
|
264
263
|
output: Optional[List[WorkflowSteps]]
|
265
264
|
error_message: Optional[str] = None
|
265
|
+
|
266
|
+
|
267
|
+
class ForkWorkflowBody(TypedDict):
|
268
|
+
workflow_id: str
|
269
|
+
start_step: int
|
270
|
+
application_version: Optional[str]
|
271
|
+
new_workflow_id: Optional[str]
|
272
|
+
|
273
|
+
|
274
|
+
@dataclass
|
275
|
+
class ForkWorkflowRequest(BaseMessage):
|
276
|
+
body: ForkWorkflowBody
|
277
|
+
|
278
|
+
|
279
|
+
@dataclass
|
280
|
+
class ForkWorkflowResponse(BaseMessage):
|
281
|
+
new_workflow_id: Optional[str]
|
282
|
+
error_message: Optional[str] = None
|
dbos/_dbos_config.py
CHANGED
@@ -436,22 +436,19 @@ def overwrite_config(provided_config: ConfigFile) -> ConfigFile:
|
|
436
436
|
# Name
|
437
437
|
provided_config["name"] = config_from_file["name"]
|
438
438
|
|
439
|
-
# Database config.
|
439
|
+
# Database config. Expects DBOS_DATABASE_URL to be set
|
440
440
|
if "database" not in provided_config:
|
441
441
|
provided_config["database"] = {}
|
442
|
-
provided_config["database"]["hostname"] = config_from_file["database"]["hostname"]
|
443
|
-
provided_config["database"]["port"] = config_from_file["database"]["port"]
|
444
|
-
provided_config["database"]["username"] = config_from_file["database"]["username"]
|
445
|
-
provided_config["database"]["password"] = config_from_file["database"]["password"]
|
446
|
-
provided_config["database"]["app_db_name"] = config_from_file["database"][
|
447
|
-
"app_db_name"
|
448
|
-
]
|
449
442
|
provided_config["database"]["sys_db_name"] = config_from_file["database"][
|
450
443
|
"sys_db_name"
|
451
444
|
]
|
452
|
-
|
453
|
-
|
454
|
-
|
445
|
+
|
446
|
+
db_url = os.environ.get("DBOS_DATABASE_URL")
|
447
|
+
if db_url is None:
|
448
|
+
raise DBOSInitializationError(
|
449
|
+
"DBOS_DATABASE_URL environment variable is not set. This is required to connect to the database."
|
450
|
+
)
|
451
|
+
provided_config["database_url"] = db_url
|
455
452
|
|
456
453
|
# Telemetry config
|
457
454
|
if "telemetry" not in provided_config or provided_config["telemetry"] is None:
|
@@ -1,20 +1,20 @@
|
|
1
|
-
dbos-0.28.
|
2
|
-
dbos-0.28.
|
3
|
-
dbos-0.28.
|
4
|
-
dbos-0.28.
|
1
|
+
dbos-0.28.0a14.dist-info/METADATA,sha256=MqLv2EJJgoN-0tBxWmqncf_BhF0kxtouqPocYA6OiQA,13269
|
2
|
+
dbos-0.28.0a14.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
dbos-0.28.0a14.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
|
4
|
+
dbos-0.28.0a14.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=A_28_nJ1nBBYDmCxtklJR9O2v14JRMtD1rAo_D4y8Kc,9764
|
8
8
|
dbos/_app_db.py,sha256=3j8_5-MlSDY0otLRszFE-GfenU6JC20fcfSL-drSNYk,11800
|
9
9
|
dbos/_classproperty.py,sha256=f0X-_BySzn3yFDRKB2JpCbLYQ9tLwt1XftfshvY7CBs,626
|
10
10
|
dbos/_client.py,sha256=PPktnvaLfl8Fj27YoOjy_kfgeQm_c3QQZztPyts5GZo,13924
|
11
|
-
dbos/_conductor/conductor.py,sha256=
|
12
|
-
dbos/_conductor/protocol.py,sha256=
|
11
|
+
dbos/_conductor/conductor.py,sha256=o0IaZjwnZ2TOyHeP2H4iSX6UnXLXQ4uODvWAKD9hHMs,21703
|
12
|
+
dbos/_conductor/protocol.py,sha256=wgOFZxmS81bv0WCB9dAyg0s6QzldpzVKQDoSPeaX0Ws,6967
|
13
13
|
dbos/_context.py,sha256=Ly1CXF1nWxICQgIpDZSaONGlz1yERBs63gqmR-yqCzM,24476
|
14
14
|
dbos/_core.py,sha256=UDpSgRA9m_YuViNXR9tVgNFLC-zxKZPxjlkj2a-Kj00,48317
|
15
15
|
dbos/_croniter.py,sha256=XHAyUyibs_59sJQfSNWkP7rqQY6_XrlfuuCxk4jYqek,47559
|
16
16
|
dbos/_dbos.py,sha256=tPpf_X9oLtpPICryXDMc589XuFeJtZ4cIq7vmsNDcls,46220
|
17
|
-
dbos/_dbos_config.py,sha256=
|
17
|
+
dbos/_dbos_config.py,sha256=NlVAtoZG5I1e2auez3cGTatC_0HcZSzdZRJAJzUadSc,19683
|
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=EN4eVBjMT3k7O7hfqJl6mIf4sxWPsiAOM086yhcGH_g,8012
|
@@ -67,4 +67,4 @@ dbos/cli/cli.py,sha256=SFmaHlCHtOojETd-P8BpbENQvwQoyq2l2yXZhSVo-50,18892
|
|
67
67
|
dbos/dbos-config.schema.json,sha256=8KcwJb_sQc4-6tQG2TLmjE_nratfrQa0qVLl9XPsvWE,6367
|
68
68
|
dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
|
69
69
|
version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
|
70
|
-
dbos-0.28.
|
70
|
+
dbos-0.28.0a14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|