dbos 0.23.0a12__py3-none-any.whl → 0.23.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.
Potentially problematic release.
This version of dbos might be problematic. Click here for more details.
- dbos/_conductor/conductor.py +20 -1
- dbos/_conductor/protocol.py +11 -0
- dbos/_schemas/system_database.py +1 -1
- dbos/_sys_db.py +25 -22
- {dbos-0.23.0a12.dist-info → dbos-0.23.0a14.dist-info}/METADATA +1 -1
- {dbos-0.23.0a12.dist-info → dbos-0.23.0a14.dist-info}/RECORD +9 -9
- {dbos-0.23.0a12.dist-info → dbos-0.23.0a14.dist-info}/WHEEL +0 -0
- {dbos-0.23.0a12.dist-info → dbos-0.23.0a14.dist-info}/entry_points.txt +0 -0
- {dbos-0.23.0a12.dist-info → dbos-0.23.0a14.dist-info}/licenses/LICENSE +0 -0
dbos/_conductor/conductor.py
CHANGED
|
@@ -8,7 +8,7 @@ from websockets.sync.client import connect
|
|
|
8
8
|
from websockets.sync.connection import Connection
|
|
9
9
|
|
|
10
10
|
from dbos._utils import GlobalParams
|
|
11
|
-
from dbos._workflow_commands import list_queued_workflows, list_workflows
|
|
11
|
+
from dbos._workflow_commands import get_workflow, list_queued_workflows, list_workflows
|
|
12
12
|
|
|
13
13
|
from . import protocol as p
|
|
14
14
|
|
|
@@ -175,6 +175,25 @@ class ConductorWebsocket(threading.Thread):
|
|
|
175
175
|
)
|
|
176
176
|
)
|
|
177
177
|
websocket.send(list_queued_workflows_response.to_json())
|
|
178
|
+
elif type == p.MessageType.GET_WORKFLOW:
|
|
179
|
+
get_workflow_message = p.GetWorkflowRequest.from_json(
|
|
180
|
+
message
|
|
181
|
+
)
|
|
182
|
+
info = get_workflow(
|
|
183
|
+
self.dbos._sys_db,
|
|
184
|
+
get_workflow_message.workflow_id,
|
|
185
|
+
getRequest=False,
|
|
186
|
+
)
|
|
187
|
+
get_workflow_response = p.GetWorkflowResponse(
|
|
188
|
+
type=p.MessageType.GET_WORKFLOW,
|
|
189
|
+
request_id=base_message.request_id,
|
|
190
|
+
output=(
|
|
191
|
+
p.WorkflowsOutput.from_workflow_information(info)
|
|
192
|
+
if info is not None
|
|
193
|
+
else None
|
|
194
|
+
),
|
|
195
|
+
)
|
|
196
|
+
websocket.send(get_workflow_response.to_json())
|
|
178
197
|
else:
|
|
179
198
|
self.dbos.logger.warning(f"Unexpected message type: {type}")
|
|
180
199
|
except ConnectionClosedOK:
|
dbos/_conductor/protocol.py
CHANGED
|
@@ -14,6 +14,7 @@ class MessageType(str, Enum):
|
|
|
14
14
|
LIST_QUEUED_WORKFLOWS = "list_queued_workflows"
|
|
15
15
|
RESUME = "resume"
|
|
16
16
|
RESTART = "restart"
|
|
17
|
+
GET_WORKFLOW = "get_workflow"
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
T = TypeVar("T", bound="BaseMessage")
|
|
@@ -184,3 +185,13 @@ class ListQueuedWorkflowsRequest(BaseMessage):
|
|
|
184
185
|
@dataclass
|
|
185
186
|
class ListQueuedWorkflowsResponse(BaseMessage):
|
|
186
187
|
output: List[WorkflowsOutput]
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@dataclass
|
|
191
|
+
class GetWorkflowRequest(BaseMessage):
|
|
192
|
+
workflow_id: str
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@dataclass
|
|
196
|
+
class GetWorkflowResponse(BaseMessage):
|
|
197
|
+
output: Optional[WorkflowsOutput]
|
dbos/_schemas/system_database.py
CHANGED
|
@@ -154,7 +154,7 @@ class SystemSchema:
|
|
|
154
154
|
nullable=False,
|
|
155
155
|
primary_key=True,
|
|
156
156
|
),
|
|
157
|
-
Column("executor_id", Text),
|
|
157
|
+
# Column("executor_id", Text), # This column is deprecated. Do *not* use it.
|
|
158
158
|
Column("queue_name", Text, nullable=False),
|
|
159
159
|
Column(
|
|
160
160
|
"created_at_epoch_ms",
|
dbos/_sys_db.py
CHANGED
|
@@ -1324,24 +1324,32 @@ class SystemDatabase:
|
|
|
1324
1324
|
# If there is a global or local concurrency limit N, select only the N oldest enqueued
|
|
1325
1325
|
# functions, else select all of them.
|
|
1326
1326
|
|
|
1327
|
-
# First lets figure out how many tasks
|
|
1327
|
+
# First lets figure out how many tasks are eligible for dequeue.
|
|
1328
|
+
# This means figuring out how many unstarted tasks are within the local and global concurrency limits
|
|
1328
1329
|
running_tasks_query = (
|
|
1329
1330
|
sa.select(
|
|
1330
|
-
SystemSchema.
|
|
1331
|
+
SystemSchema.workflow_status.c.executor_id,
|
|
1331
1332
|
sa.func.count().label("task_count"),
|
|
1332
1333
|
)
|
|
1334
|
+
.select_from(
|
|
1335
|
+
SystemSchema.workflow_queue.join(
|
|
1336
|
+
SystemSchema.workflow_status,
|
|
1337
|
+
SystemSchema.workflow_queue.c.workflow_uuid
|
|
1338
|
+
== SystemSchema.workflow_status.c.workflow_uuid,
|
|
1339
|
+
)
|
|
1340
|
+
)
|
|
1333
1341
|
.where(SystemSchema.workflow_queue.c.queue_name == queue.name)
|
|
1334
1342
|
.where(
|
|
1335
|
-
SystemSchema.workflow_queue.c.
|
|
1343
|
+
SystemSchema.workflow_queue.c.started_at_epoch_ms.isnot(
|
|
1336
1344
|
None
|
|
1337
|
-
) # Task is
|
|
1345
|
+
) # Task is started
|
|
1338
1346
|
)
|
|
1339
1347
|
.where(
|
|
1340
1348
|
SystemSchema.workflow_queue.c.completed_at_epoch_ms.is_(
|
|
1341
1349
|
None
|
|
1342
|
-
) # Task is not completed
|
|
1350
|
+
) # Task is not completed.
|
|
1343
1351
|
)
|
|
1344
|
-
.group_by(SystemSchema.
|
|
1352
|
+
.group_by(SystemSchema.workflow_status.c.executor_id)
|
|
1345
1353
|
)
|
|
1346
1354
|
running_tasks_result = c.execute(running_tasks_query).fetchall()
|
|
1347
1355
|
running_tasks_result_dict = {row[0]: row[1] for row in running_tasks_result}
|
|
@@ -1351,12 +1359,6 @@ class SystemDatabase:
|
|
|
1351
1359
|
|
|
1352
1360
|
max_tasks = float("inf")
|
|
1353
1361
|
if queue.worker_concurrency is not None:
|
|
1354
|
-
# Worker local concurrency limit should always be >= running_tasks_for_this_worker
|
|
1355
|
-
# This should never happen but a check + warning doesn't hurt
|
|
1356
|
-
if running_tasks_for_this_worker > queue.worker_concurrency:
|
|
1357
|
-
dbos_logger.warning(
|
|
1358
|
-
f"Number of tasks on this worker ({running_tasks_for_this_worker}) exceeds the worker concurrency limit ({queue.worker_concurrency})"
|
|
1359
|
-
)
|
|
1360
1362
|
max_tasks = max(
|
|
1361
1363
|
0, queue.worker_concurrency - running_tasks_for_this_worker
|
|
1362
1364
|
)
|
|
@@ -1371,16 +1373,14 @@ class SystemDatabase:
|
|
|
1371
1373
|
available_tasks = max(0, queue.concurrency - total_running_tasks)
|
|
1372
1374
|
max_tasks = min(max_tasks, available_tasks)
|
|
1373
1375
|
|
|
1374
|
-
# Lookup tasks
|
|
1376
|
+
# Lookup unstarted/uncompleted tasks (not running)
|
|
1375
1377
|
query = (
|
|
1376
1378
|
sa.select(
|
|
1377
1379
|
SystemSchema.workflow_queue.c.workflow_uuid,
|
|
1378
|
-
SystemSchema.workflow_queue.c.started_at_epoch_ms,
|
|
1379
|
-
SystemSchema.workflow_queue.c.executor_id,
|
|
1380
1380
|
)
|
|
1381
1381
|
.where(SystemSchema.workflow_queue.c.queue_name == queue.name)
|
|
1382
|
+
.where(SystemSchema.workflow_queue.c.started_at_epoch_ms == None)
|
|
1382
1383
|
.where(SystemSchema.workflow_queue.c.completed_at_epoch_ms == None)
|
|
1383
|
-
.where(SystemSchema.workflow_queue.c.executor_id == None)
|
|
1384
1384
|
.order_by(SystemSchema.workflow_queue.c.created_at_epoch_ms.asc())
|
|
1385
1385
|
.with_for_update(nowait=True) # Error out early
|
|
1386
1386
|
)
|
|
@@ -1423,7 +1423,7 @@ class SystemDatabase:
|
|
|
1423
1423
|
c.execute(
|
|
1424
1424
|
SystemSchema.workflow_queue.update()
|
|
1425
1425
|
.where(SystemSchema.workflow_queue.c.workflow_uuid == id)
|
|
1426
|
-
.values(started_at_epoch_ms=start_time_ms
|
|
1426
|
+
.values(started_at_epoch_ms=start_time_ms)
|
|
1427
1427
|
)
|
|
1428
1428
|
ret_ids.append(id)
|
|
1429
1429
|
|
|
@@ -1468,23 +1468,26 @@ class SystemDatabase:
|
|
|
1468
1468
|
|
|
1469
1469
|
with self.engine.connect() as conn:
|
|
1470
1470
|
with conn.begin() as transaction:
|
|
1471
|
+
# Reset the start time in the queue to mark it as not started
|
|
1471
1472
|
res = conn.execute(
|
|
1472
1473
|
sa.update(SystemSchema.workflow_queue)
|
|
1473
1474
|
.where(SystemSchema.workflow_queue.c.workflow_uuid == workflow_id)
|
|
1474
|
-
.
|
|
1475
|
+
.where(
|
|
1476
|
+
SystemSchema.workflow_queue.c.completed_at_epoch_ms.is_(None)
|
|
1477
|
+
)
|
|
1478
|
+
.values(started_at_epoch_ms=None)
|
|
1475
1479
|
)
|
|
1476
1480
|
|
|
1477
|
-
# If no rows were affected, the workflow is not anymore in the queue
|
|
1481
|
+
# If no rows were affected, the workflow is not anymore in the queue or was already completed
|
|
1478
1482
|
if res.rowcount == 0:
|
|
1479
1483
|
transaction.rollback()
|
|
1480
1484
|
return False
|
|
1481
1485
|
|
|
1486
|
+
# Reset the status of the task to "ENQUEUED"
|
|
1482
1487
|
res = conn.execute(
|
|
1483
1488
|
sa.update(SystemSchema.workflow_status)
|
|
1484
1489
|
.where(SystemSchema.workflow_status.c.workflow_uuid == workflow_id)
|
|
1485
|
-
.values(
|
|
1486
|
-
executor_id=None, status=WorkflowStatusString.ENQUEUED.value
|
|
1487
|
-
)
|
|
1490
|
+
.values(status=WorkflowStatusString.ENQUEUED.value)
|
|
1488
1491
|
)
|
|
1489
1492
|
if res.rowcount == 0:
|
|
1490
1493
|
# This should never happen
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
dbos-0.23.
|
|
2
|
-
dbos-0.23.
|
|
3
|
-
dbos-0.23.
|
|
4
|
-
dbos-0.23.
|
|
1
|
+
dbos-0.23.0a14.dist-info/METADATA,sha256=z88O0QiIfVU-VrNs6Udtgiw5G0asAkl6x6ugTrG7wHk,5556
|
|
2
|
+
dbos-0.23.0a14.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
|
|
3
|
+
dbos-0.23.0a14.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
|
|
4
|
+
dbos-0.23.0a14.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
|
|
5
5
|
dbos/__init__.py,sha256=CxRHBHEthPL4PZoLbZhp3rdm44-KkRTT2-7DkK9d4QQ,724
|
|
6
6
|
dbos/__main__.py,sha256=P7jAr-7L9XE5mrsQ7i4b-bLr2ap1tCQfhMByLCRWDj0,568
|
|
7
7
|
dbos/_admin_server.py,sha256=YiVn5lywz2Vg8_juyNHOYl0HVEy48--7b4phwK7r92o,5732
|
|
@@ -10,8 +10,8 @@ dbos/_classproperty.py,sha256=f0X-_BySzn3yFDRKB2JpCbLYQ9tLwt1XftfshvY7CBs,626
|
|
|
10
10
|
dbos/_cloudutils/authentication.py,sha256=V0fCWQN9stCkhbuuxgPTGpvuQcDqfU3KAxPAh01vKW4,5007
|
|
11
11
|
dbos/_cloudutils/cloudutils.py,sha256=YC7jGsIopT0KveLsqbRpQk2KlRBk-nIRC_UCgep4f3o,7797
|
|
12
12
|
dbos/_cloudutils/databases.py,sha256=_shqaqSvhY4n2ScgQ8IP5PDZvzvcx3YBKV8fj-cxhSY,8543
|
|
13
|
-
dbos/_conductor/conductor.py,sha256=
|
|
14
|
-
dbos/_conductor/protocol.py,sha256=
|
|
13
|
+
dbos/_conductor/conductor.py,sha256=uX6DsAw0vpu4Gf5pxZJL7YrMSfJptCvRCnt14AUURFo,11123
|
|
14
|
+
dbos/_conductor/protocol.py,sha256=HLHS1bOdFdQhwA05wXDCd3O704ki72ju1UUBXz0UB-0,4841
|
|
15
15
|
dbos/_context.py,sha256=Ue5qu3rzLfRmPkz-UUZi9ZS8iXpapRN0NTM4mbA2QmQ,17738
|
|
16
16
|
dbos/_core.py,sha256=UQb068FT59Op-F5RmtxreSeSQ1_wljOso0dQCUOPrC4,37528
|
|
17
17
|
dbos/_croniter.py,sha256=XHAyUyibs_59sJQfSNWkP7rqQY6_XrlfuuCxk4jYqek,47559
|
|
@@ -43,9 +43,9 @@ dbos/_roles.py,sha256=iOsgmIAf1XVzxs3gYWdGRe1B880YfOw5fpU7Jwx8_A8,2271
|
|
|
43
43
|
dbos/_scheduler.py,sha256=0I3e8Y-OIBG3wiUCIskShd-Sk_eUFCFyRB5u4L7IHXI,1940
|
|
44
44
|
dbos/_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
45
|
dbos/_schemas/application_database.py,sha256=KeyoPrF7hy_ODXV7QNike_VFSD74QBRfQ76D7QyE9HI,966
|
|
46
|
-
dbos/_schemas/system_database.py,sha256=
|
|
46
|
+
dbos/_schemas/system_database.py,sha256=16146P4TLjAGjTYykOs_KUd2c_geJ5fuhk0ko85C65M,5211
|
|
47
47
|
dbos/_serialization.py,sha256=YCYv0qKAwAZ1djZisBC7khvKqG-5OcIv9t9EC5PFIog,1743
|
|
48
|
-
dbos/_sys_db.py,sha256=
|
|
48
|
+
dbos/_sys_db.py,sha256=ul17Pe_qmslBMU1UZpY_UpCGnvUhcAxLAbSBps0YB20,64587
|
|
49
49
|
dbos/_templates/dbos-db-starter/README.md,sha256=GhxhBj42wjTt1fWEtwNriHbJuKb66Vzu89G4pxNHw2g,930
|
|
50
50
|
dbos/_templates/dbos-db-starter/__package/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
51
|
dbos/_templates/dbos-db-starter/__package/main.py,sha256=eI0SS9Nwj-fldtiuSzIlIG6dC91GXXwdRsoHxv6S_WI,2719
|
|
@@ -65,4 +65,4 @@ dbos/cli/cli.py,sha256=ThomRytw7EP5iOcrjEgwnpaWgXNTLfnFEBBvCGHxtJs,15590
|
|
|
65
65
|
dbos/dbos-config.schema.json,sha256=X5TpXNcARGceX0zQs0fVgtZW_Xj9uBbY5afPt9Rz9yk,5741
|
|
66
66
|
dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
|
|
67
67
|
version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
|
|
68
|
-
dbos-0.23.
|
|
68
|
+
dbos-0.23.0a14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|