dbos 0.27.0a8__py3-none-any.whl → 0.27.0a10__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.
Potentially problematic release.
This version of dbos might be problematic. Click here for more details.
- dbos/_admin_server.py +4 -3
- dbos/_client.py +30 -9
- dbos/_dbos.py +8 -1
- dbos/_sys_db.py +17 -6
- dbos/_workflow_commands.py +15 -2
- {dbos-0.27.0a8.dist-info → dbos-0.27.0a10.dist-info}/METADATA +1 -1
- {dbos-0.27.0a8.dist-info → dbos-0.27.0a10.dist-info}/RECORD +10 -10
- {dbos-0.27.0a8.dist-info → dbos-0.27.0a10.dist-info}/WHEEL +0 -0
- {dbos-0.27.0a8.dist-info → dbos-0.27.0a10.dist-info}/entry_points.txt +0 -0
- {dbos-0.27.0a8.dist-info → dbos-0.27.0a10.dist-info}/licenses/LICENSE +0 -0
dbos/_admin_server.py
CHANGED
|
@@ -45,9 +45,10 @@ class AdminServer:
|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class AdminRequestHandler(BaseHTTPRequestHandler):
|
|
48
|
+
is_deactivated = False
|
|
49
|
+
|
|
48
50
|
def __init__(self, dbos: DBOS, *args: Any, **kwargs: Any) -> None:
|
|
49
51
|
self.dbos = dbos
|
|
50
|
-
self.is_deactivated = False
|
|
51
52
|
super().__init__(*args, **kwargs)
|
|
52
53
|
|
|
53
54
|
def _end_headers(self) -> None:
|
|
@@ -63,11 +64,11 @@ class AdminRequestHandler(BaseHTTPRequestHandler):
|
|
|
63
64
|
self._end_headers()
|
|
64
65
|
self.wfile.write("healthy".encode("utf-8"))
|
|
65
66
|
elif self.path == _deactivate_path:
|
|
66
|
-
if not
|
|
67
|
+
if not AdminRequestHandler.is_deactivated:
|
|
67
68
|
dbos_logger.info(
|
|
68
69
|
f"Deactivating DBOS executor {GlobalParams.executor_id} with version {GlobalParams.app_version}. This executor will complete existing workflows but will not start new workflows."
|
|
69
70
|
)
|
|
70
|
-
|
|
71
|
+
AdminRequestHandler.is_deactivated = True
|
|
71
72
|
# Stop all scheduled workflows, queues, and kafka loops
|
|
72
73
|
for event in self.dbos.stop_events:
|
|
73
74
|
event.set()
|
dbos/_client.py
CHANGED
|
@@ -243,11 +243,13 @@ class DBOSClient:
|
|
|
243
243
|
async def cancel_workflow_async(self, workflow_id: str) -> None:
|
|
244
244
|
await asyncio.to_thread(self.cancel_workflow, workflow_id)
|
|
245
245
|
|
|
246
|
-
def resume_workflow(self, workflow_id: str) ->
|
|
246
|
+
def resume_workflow(self, workflow_id: str) -> WorkflowHandle[Any]:
|
|
247
247
|
self._sys_db.resume_workflow(workflow_id)
|
|
248
|
+
return WorkflowHandleClientPolling[Any](workflow_id, self._sys_db)
|
|
248
249
|
|
|
249
|
-
async def resume_workflow_async(self, workflow_id: str) ->
|
|
250
|
+
async def resume_workflow_async(self, workflow_id: str) -> WorkflowHandleAsync[Any]:
|
|
250
251
|
await asyncio.to_thread(self.resume_workflow, workflow_id)
|
|
252
|
+
return WorkflowHandleClientAsyncPolling[Any](workflow_id, self._sys_db)
|
|
251
253
|
|
|
252
254
|
def list_workflows(
|
|
253
255
|
self,
|
|
@@ -361,16 +363,35 @@ class DBOSClient:
|
|
|
361
363
|
async def list_workflow_steps_async(self, workflow_id: str) -> List[StepInfo]:
|
|
362
364
|
return await asyncio.to_thread(self.list_workflow_steps, workflow_id)
|
|
363
365
|
|
|
364
|
-
def fork_workflow(
|
|
366
|
+
def fork_workflow(
|
|
367
|
+
self,
|
|
368
|
+
workflow_id: str,
|
|
369
|
+
start_step: int,
|
|
370
|
+
*,
|
|
371
|
+
application_version: Optional[str] = None,
|
|
372
|
+
) -> WorkflowHandle[Any]:
|
|
365
373
|
forked_workflow_id = fork_workflow(
|
|
366
|
-
self._sys_db,
|
|
374
|
+
self._sys_db,
|
|
375
|
+
self._app_db,
|
|
376
|
+
workflow_id,
|
|
377
|
+
start_step,
|
|
378
|
+
application_version=application_version,
|
|
367
379
|
)
|
|
368
|
-
return WorkflowHandleClientPolling[
|
|
380
|
+
return WorkflowHandleClientPolling[Any](forked_workflow_id, self._sys_db)
|
|
369
381
|
|
|
370
382
|
async def fork_workflow_async(
|
|
371
|
-
self,
|
|
372
|
-
|
|
383
|
+
self,
|
|
384
|
+
workflow_id: str,
|
|
385
|
+
start_step: int,
|
|
386
|
+
*,
|
|
387
|
+
application_version: Optional[str] = None,
|
|
388
|
+
) -> WorkflowHandleAsync[Any]:
|
|
373
389
|
forked_workflow_id = await asyncio.to_thread(
|
|
374
|
-
fork_workflow,
|
|
390
|
+
fork_workflow,
|
|
391
|
+
self._sys_db,
|
|
392
|
+
self._app_db,
|
|
393
|
+
workflow_id,
|
|
394
|
+
start_step,
|
|
395
|
+
application_version=application_version,
|
|
375
396
|
)
|
|
376
|
-
return WorkflowHandleClientAsyncPolling[
|
|
397
|
+
return WorkflowHandleClientAsyncPolling[Any](forked_workflow_id, self._sys_db)
|
dbos/_dbos.py
CHANGED
|
@@ -978,7 +978,13 @@ class DBOS:
|
|
|
978
978
|
return cls.fork_workflow(workflow_id, 1)
|
|
979
979
|
|
|
980
980
|
@classmethod
|
|
981
|
-
def fork_workflow(
|
|
981
|
+
def fork_workflow(
|
|
982
|
+
cls,
|
|
983
|
+
workflow_id: str,
|
|
984
|
+
start_step: int,
|
|
985
|
+
*,
|
|
986
|
+
application_version: Optional[str] = None,
|
|
987
|
+
) -> WorkflowHandle[Any]:
|
|
982
988
|
"""Restart a workflow with a new workflow ID from a specific step"""
|
|
983
989
|
|
|
984
990
|
def fn() -> str:
|
|
@@ -988,6 +994,7 @@ class DBOS:
|
|
|
988
994
|
_get_dbos_instance()._app_db,
|
|
989
995
|
workflow_id,
|
|
990
996
|
start_step,
|
|
997
|
+
application_version=application_version,
|
|
991
998
|
)
|
|
992
999
|
|
|
993
1000
|
new_id = _get_dbos_instance()._sys_db.call_function_as_step(
|
dbos/_sys_db.py
CHANGED
|
@@ -544,15 +544,17 @@ class SystemDatabase:
|
|
|
544
544
|
# Execute with snapshot isolation in case of concurrent calls on the same workflow
|
|
545
545
|
c.execute(sa.text("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ"))
|
|
546
546
|
# Check the status of the workflow. If it is complete, do nothing.
|
|
547
|
-
|
|
547
|
+
status_row = c.execute(
|
|
548
548
|
sa.select(
|
|
549
549
|
SystemSchema.workflow_status.c.status,
|
|
550
550
|
).where(SystemSchema.workflow_status.c.workflow_uuid == workflow_id)
|
|
551
551
|
).fetchone()
|
|
552
|
+
if status_row is None:
|
|
553
|
+
return
|
|
554
|
+
status = status_row[0]
|
|
552
555
|
if (
|
|
553
|
-
|
|
554
|
-
or
|
|
555
|
-
or row[0] == WorkflowStatusString.ERROR.value
|
|
556
|
+
status == WorkflowStatusString.SUCCESS.value
|
|
557
|
+
or status == WorkflowStatusString.ERROR.value
|
|
556
558
|
):
|
|
557
559
|
return
|
|
558
560
|
# Remove the workflow from the queues table so resume can safely be called on an ENQUEUED workflow
|
|
@@ -592,7 +594,12 @@ class SystemDatabase:
|
|
|
592
594
|
return max_function_id
|
|
593
595
|
|
|
594
596
|
def fork_workflow(
|
|
595
|
-
self,
|
|
597
|
+
self,
|
|
598
|
+
original_workflow_id: str,
|
|
599
|
+
forked_workflow_id: str,
|
|
600
|
+
start_step: int,
|
|
601
|
+
*,
|
|
602
|
+
application_version: Optional[str],
|
|
596
603
|
) -> str:
|
|
597
604
|
|
|
598
605
|
status = self.get_workflow_status(original_workflow_id)
|
|
@@ -612,7 +619,11 @@ class SystemDatabase:
|
|
|
612
619
|
name=status["name"],
|
|
613
620
|
class_name=status["class_name"],
|
|
614
621
|
config_name=status["config_name"],
|
|
615
|
-
application_version=
|
|
622
|
+
application_version=(
|
|
623
|
+
application_version
|
|
624
|
+
if application_version is not None
|
|
625
|
+
else status["app_version"]
|
|
626
|
+
),
|
|
616
627
|
application_id=status["app_id"],
|
|
617
628
|
request=status["request"],
|
|
618
629
|
authenticated_user=status["authenticated_user"],
|
dbos/_workflow_commands.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
from typing import List, Optional
|
|
3
3
|
|
|
4
|
+
from dbos._context import get_local_dbos_context
|
|
4
5
|
from dbos._error import DBOSException
|
|
5
6
|
|
|
6
7
|
from ._app_db import ApplicationDatabase
|
|
@@ -103,6 +104,8 @@ def fork_workflow(
|
|
|
103
104
|
app_db: ApplicationDatabase,
|
|
104
105
|
workflow_id: str,
|
|
105
106
|
start_step: int,
|
|
107
|
+
*,
|
|
108
|
+
application_version: Optional[str],
|
|
106
109
|
) -> str:
|
|
107
110
|
def get_max_function_id(workflow_uuid: str) -> int:
|
|
108
111
|
max_transactions = app_db.get_max_function_id(workflow_uuid) or 0
|
|
@@ -114,7 +117,17 @@ def fork_workflow(
|
|
|
114
117
|
raise DBOSException(
|
|
115
118
|
f"Cannot fork workflow {workflow_id} from step {start_step}. The workflow has {max_function_id} steps."
|
|
116
119
|
)
|
|
117
|
-
|
|
120
|
+
ctx = get_local_dbos_context()
|
|
121
|
+
if ctx is not None and len(ctx.id_assigned_for_next_workflow) > 0:
|
|
122
|
+
forked_workflow_id = ctx.id_assigned_for_next_workflow
|
|
123
|
+
ctx.id_assigned_for_next_workflow = ""
|
|
124
|
+
else:
|
|
125
|
+
forked_workflow_id = str(uuid.uuid4())
|
|
118
126
|
app_db.clone_workflow_transactions(workflow_id, forked_workflow_id, start_step)
|
|
119
|
-
sys_db.fork_workflow(
|
|
127
|
+
sys_db.fork_workflow(
|
|
128
|
+
workflow_id,
|
|
129
|
+
forked_workflow_id,
|
|
130
|
+
start_step,
|
|
131
|
+
application_version=application_version,
|
|
132
|
+
)
|
|
120
133
|
return forked_workflow_id
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
dbos-0.27.
|
|
2
|
-
dbos-0.27.
|
|
3
|
-
dbos-0.27.
|
|
4
|
-
dbos-0.27.
|
|
1
|
+
dbos-0.27.0a10.dist-info/METADATA,sha256=Gfag7_gwehHpSgpOJistZUvK08cQVC4C0ignrfpmvSM,5554
|
|
2
|
+
dbos-0.27.0a10.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
|
3
|
+
dbos-0.27.0a10.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
|
|
4
|
+
dbos-0.27.0a10.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
|
|
5
5
|
dbos/__init__.py,sha256=-FdBlOlr-f2tY__C23J4v22MoCAXqcDN_-zXsJXdoZ0,1005
|
|
6
6
|
dbos/__main__.py,sha256=G7Exn-MhGrVJVDbgNlpzhfh8WMX_72t3_oJaFT9Lmt8,653
|
|
7
|
-
dbos/_admin_server.py,sha256=
|
|
7
|
+
dbos/_admin_server.py,sha256=NG0JWQQer9kEslPNAA0dBv-O262sjarz7ZSlv8yird0,9053
|
|
8
8
|
dbos/_app_db.py,sha256=3j8_5-MlSDY0otLRszFE-GfenU6JC20fcfSL-drSNYk,11800
|
|
9
9
|
dbos/_classproperty.py,sha256=f0X-_BySzn3yFDRKB2JpCbLYQ9tLwt1XftfshvY7CBs,626
|
|
10
|
-
dbos/_client.py,sha256=
|
|
10
|
+
dbos/_client.py,sha256=Id-jzAUH6JMN-9WmAGyo0vm-nc0URjNIVwA2iKnCN5Q,13418
|
|
11
11
|
dbos/_conductor/conductor.py,sha256=HYzVL29IMMrs2Mnms_7cHJynCnmmEN5SDQOMjzn3UoU,16840
|
|
12
12
|
dbos/_conductor/protocol.py,sha256=zEKIuOQdIaSduNqfZKpo8PSD9_1oNpKIPnBNCu3RUyE,6681
|
|
13
13
|
dbos/_context.py,sha256=5aJHOjh6-2Zc7Fwzw924Vg0utLEkaR-oBMRdz3cE95k,23680
|
|
14
14
|
dbos/_core.py,sha256=7zhdO-VfZe84wgOzBVsliqO-BI20OzcLTFqvrGyxttw,48425
|
|
15
15
|
dbos/_croniter.py,sha256=XHAyUyibs_59sJQfSNWkP7rqQY6_XrlfuuCxk4jYqek,47559
|
|
16
|
-
dbos/_dbos.py,sha256=
|
|
16
|
+
dbos/_dbos.py,sha256=ENDQ6Xi4MoKrjXoCRlk1B64yZP7D-MyDUjUlOTRsw9I,48314
|
|
17
17
|
dbos/_dbos_config.py,sha256=L0Z0OOB5FoPM9g-joZqXGeJnlxWQsEUtgPtgtg9Uf48,21732
|
|
18
18
|
dbos/_debug.py,sha256=MNlQVZ6TscGCRQeEEL0VE8Uignvr6dPeDDDefS3xgIE,1823
|
|
19
19
|
dbos/_docker_pg_helper.py,sha256=NmcgqmR5rQA_4igfeqh8ugNT2z3YmoOvuep_MEtxTiY,5854
|
|
@@ -47,7 +47,7 @@ dbos/_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
47
47
|
dbos/_schemas/application_database.py,sha256=SypAS9l9EsaBHFn9FR8jmnqt01M74d9AF1AMa4m2hhI,1040
|
|
48
48
|
dbos/_schemas/system_database.py,sha256=wLqrhApNqrwZC1SdUxi_ca0y_66WzKaaBOxvND4_bdg,5738
|
|
49
49
|
dbos/_serialization.py,sha256=YCYv0qKAwAZ1djZisBC7khvKqG-5OcIv9t9EC5PFIog,1743
|
|
50
|
-
dbos/_sys_db.py,sha256=
|
|
50
|
+
dbos/_sys_db.py,sha256=CJf-PgAerEZdbCe9ZJOJnjkrqPcflUz04KFJaGRMm7Q,82389
|
|
51
51
|
dbos/_templates/dbos-db-starter/README.md,sha256=GhxhBj42wjTt1fWEtwNriHbJuKb66Vzu89G4pxNHw2g,930
|
|
52
52
|
dbos/_templates/dbos-db-starter/__package/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
53
|
dbos/_templates/dbos-db-starter/__package/main.py,sha256=nJMN3ZD2lmwg4Dcgmiwqc-tQGuCJuJal2Xl85iA277U,2453
|
|
@@ -60,11 +60,11 @@ dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py,sh
|
|
|
60
60
|
dbos/_templates/dbos-db-starter/start_postgres_docker.py,sha256=lQVLlYO5YkhGPEgPqwGc7Y8uDKse9HsWv5fynJEFJHM,1681
|
|
61
61
|
dbos/_tracer.py,sha256=yN6GRDKu_1p-EqtQLNarMocPfga2ZuqpzStzzSPYhzo,2732
|
|
62
62
|
dbos/_utils.py,sha256=nFRUHzVjXG5AusF85AlYHikj63Tzi-kQm992ihsrAxA,201
|
|
63
|
-
dbos/_workflow_commands.py,sha256=
|
|
63
|
+
dbos/_workflow_commands.py,sha256=7_f8-w0MbS1gqC5v68EwzbUtomVM0lLebozpHxXmRYg,3982
|
|
64
64
|
dbos/cli/_github_init.py,sha256=Y_bDF9gfO2jB1id4FV5h1oIxEJRWyqVjhb7bNEa5nQ0,3224
|
|
65
65
|
dbos/cli/_template_init.py,sha256=-WW3kbq0W_Tq4WbMqb1UGJG3xvJb3woEY5VspG95Srk,2857
|
|
66
66
|
dbos/cli/cli.py,sha256=a3rUrHog5-e22KjjUPOuTjH20PmUgSP0amRpMd6LVJE,18882
|
|
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.27.
|
|
70
|
+
dbos-0.27.0a10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|