dbos 0.23.0a13__py3-none-any.whl → 0.24.0a1__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/_scheduler.py +5 -2
- dbos/_schemas/system_database.py +1 -1
- dbos/_sys_db.py +30 -23
- {dbos-0.23.0a13.dist-info → dbos-0.24.0a1.dist-info}/METADATA +1 -1
- {dbos-0.23.0a13.dist-info → dbos-0.24.0a1.dist-info}/RECORD +8 -8
- {dbos-0.23.0a13.dist-info → dbos-0.24.0a1.dist-info}/WHEEL +0 -0
- {dbos-0.23.0a13.dist-info → dbos-0.24.0a1.dist-info}/entry_points.txt +0 -0
- {dbos-0.23.0a13.dist-info → dbos-0.24.0a1.dist-info}/licenses/LICENSE +0 -0
dbos/_scheduler.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import threading
|
|
2
|
+
import traceback
|
|
2
3
|
from datetime import datetime, timezone
|
|
3
4
|
from typing import TYPE_CHECKING, Callable
|
|
4
5
|
|
|
@@ -33,8 +34,10 @@ def scheduler_loop(
|
|
|
33
34
|
with SetWorkflowID(f"sched-{func.__qualname__}-{nextExecTime.isoformat()}"):
|
|
34
35
|
try:
|
|
35
36
|
scheduler_queue.enqueue(func, nextExecTime, datetime.now(timezone.utc))
|
|
36
|
-
except Exception
|
|
37
|
-
dbos_logger.warning(
|
|
37
|
+
except Exception:
|
|
38
|
+
dbos_logger.warning(
|
|
39
|
+
f"Exception encountered in scheduler thread: {traceback.format_exc()})"
|
|
40
|
+
)
|
|
38
41
|
|
|
39
42
|
|
|
40
43
|
def scheduled(
|
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
|
@@ -202,7 +202,11 @@ class SystemDatabase:
|
|
|
202
202
|
|
|
203
203
|
# Create a connection pool for the system database
|
|
204
204
|
self.engine = sa.create_engine(
|
|
205
|
-
system_db_url,
|
|
205
|
+
system_db_url,
|
|
206
|
+
pool_size=20,
|
|
207
|
+
max_overflow=5,
|
|
208
|
+
pool_timeout=30,
|
|
209
|
+
connect_args={"connect_timeout": 10},
|
|
206
210
|
)
|
|
207
211
|
|
|
208
212
|
# Run a schema migration for the system database
|
|
@@ -1324,24 +1328,32 @@ class SystemDatabase:
|
|
|
1324
1328
|
# If there is a global or local concurrency limit N, select only the N oldest enqueued
|
|
1325
1329
|
# functions, else select all of them.
|
|
1326
1330
|
|
|
1327
|
-
# First lets figure out how many tasks
|
|
1331
|
+
# First lets figure out how many tasks are eligible for dequeue.
|
|
1332
|
+
# This means figuring out how many unstarted tasks are within the local and global concurrency limits
|
|
1328
1333
|
running_tasks_query = (
|
|
1329
1334
|
sa.select(
|
|
1330
|
-
SystemSchema.
|
|
1335
|
+
SystemSchema.workflow_status.c.executor_id,
|
|
1331
1336
|
sa.func.count().label("task_count"),
|
|
1332
1337
|
)
|
|
1338
|
+
.select_from(
|
|
1339
|
+
SystemSchema.workflow_queue.join(
|
|
1340
|
+
SystemSchema.workflow_status,
|
|
1341
|
+
SystemSchema.workflow_queue.c.workflow_uuid
|
|
1342
|
+
== SystemSchema.workflow_status.c.workflow_uuid,
|
|
1343
|
+
)
|
|
1344
|
+
)
|
|
1333
1345
|
.where(SystemSchema.workflow_queue.c.queue_name == queue.name)
|
|
1334
1346
|
.where(
|
|
1335
|
-
SystemSchema.workflow_queue.c.
|
|
1347
|
+
SystemSchema.workflow_queue.c.started_at_epoch_ms.isnot(
|
|
1336
1348
|
None
|
|
1337
|
-
) # Task is
|
|
1349
|
+
) # Task is started
|
|
1338
1350
|
)
|
|
1339
1351
|
.where(
|
|
1340
1352
|
SystemSchema.workflow_queue.c.completed_at_epoch_ms.is_(
|
|
1341
1353
|
None
|
|
1342
|
-
) # Task is not completed
|
|
1354
|
+
) # Task is not completed.
|
|
1343
1355
|
)
|
|
1344
|
-
.group_by(SystemSchema.
|
|
1356
|
+
.group_by(SystemSchema.workflow_status.c.executor_id)
|
|
1345
1357
|
)
|
|
1346
1358
|
running_tasks_result = c.execute(running_tasks_query).fetchall()
|
|
1347
1359
|
running_tasks_result_dict = {row[0]: row[1] for row in running_tasks_result}
|
|
@@ -1351,12 +1363,6 @@ class SystemDatabase:
|
|
|
1351
1363
|
|
|
1352
1364
|
max_tasks = float("inf")
|
|
1353
1365
|
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
1366
|
max_tasks = max(
|
|
1361
1367
|
0, queue.worker_concurrency - running_tasks_for_this_worker
|
|
1362
1368
|
)
|
|
@@ -1371,16 +1377,14 @@ class SystemDatabase:
|
|
|
1371
1377
|
available_tasks = max(0, queue.concurrency - total_running_tasks)
|
|
1372
1378
|
max_tasks = min(max_tasks, available_tasks)
|
|
1373
1379
|
|
|
1374
|
-
# Lookup tasks
|
|
1380
|
+
# Lookup unstarted/uncompleted tasks (not running)
|
|
1375
1381
|
query = (
|
|
1376
1382
|
sa.select(
|
|
1377
1383
|
SystemSchema.workflow_queue.c.workflow_uuid,
|
|
1378
|
-
SystemSchema.workflow_queue.c.started_at_epoch_ms,
|
|
1379
|
-
SystemSchema.workflow_queue.c.executor_id,
|
|
1380
1384
|
)
|
|
1381
1385
|
.where(SystemSchema.workflow_queue.c.queue_name == queue.name)
|
|
1386
|
+
.where(SystemSchema.workflow_queue.c.started_at_epoch_ms == None)
|
|
1382
1387
|
.where(SystemSchema.workflow_queue.c.completed_at_epoch_ms == None)
|
|
1383
|
-
.where(SystemSchema.workflow_queue.c.executor_id == None)
|
|
1384
1388
|
.order_by(SystemSchema.workflow_queue.c.created_at_epoch_ms.asc())
|
|
1385
1389
|
.with_for_update(nowait=True) # Error out early
|
|
1386
1390
|
)
|
|
@@ -1423,7 +1427,7 @@ class SystemDatabase:
|
|
|
1423
1427
|
c.execute(
|
|
1424
1428
|
SystemSchema.workflow_queue.update()
|
|
1425
1429
|
.where(SystemSchema.workflow_queue.c.workflow_uuid == id)
|
|
1426
|
-
.values(started_at_epoch_ms=start_time_ms
|
|
1430
|
+
.values(started_at_epoch_ms=start_time_ms)
|
|
1427
1431
|
)
|
|
1428
1432
|
ret_ids.append(id)
|
|
1429
1433
|
|
|
@@ -1468,23 +1472,26 @@ class SystemDatabase:
|
|
|
1468
1472
|
|
|
1469
1473
|
with self.engine.connect() as conn:
|
|
1470
1474
|
with conn.begin() as transaction:
|
|
1475
|
+
# Reset the start time in the queue to mark it as not started
|
|
1471
1476
|
res = conn.execute(
|
|
1472
1477
|
sa.update(SystemSchema.workflow_queue)
|
|
1473
1478
|
.where(SystemSchema.workflow_queue.c.workflow_uuid == workflow_id)
|
|
1474
|
-
.
|
|
1479
|
+
.where(
|
|
1480
|
+
SystemSchema.workflow_queue.c.completed_at_epoch_ms.is_(None)
|
|
1481
|
+
)
|
|
1482
|
+
.values(started_at_epoch_ms=None)
|
|
1475
1483
|
)
|
|
1476
1484
|
|
|
1477
|
-
# If no rows were affected, the workflow is not anymore in the queue
|
|
1485
|
+
# If no rows were affected, the workflow is not anymore in the queue or was already completed
|
|
1478
1486
|
if res.rowcount == 0:
|
|
1479
1487
|
transaction.rollback()
|
|
1480
1488
|
return False
|
|
1481
1489
|
|
|
1490
|
+
# Reset the status of the task to "ENQUEUED"
|
|
1482
1491
|
res = conn.execute(
|
|
1483
1492
|
sa.update(SystemSchema.workflow_status)
|
|
1484
1493
|
.where(SystemSchema.workflow_status.c.workflow_uuid == workflow_id)
|
|
1485
|
-
.values(
|
|
1486
|
-
executor_id=None, status=WorkflowStatusString.ENQUEUED.value
|
|
1487
|
-
)
|
|
1494
|
+
.values(status=WorkflowStatusString.ENQUEUED.value)
|
|
1488
1495
|
)
|
|
1489
1496
|
if res.rowcount == 0:
|
|
1490
1497
|
# This should never happen
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
dbos-0.
|
|
2
|
-
dbos-0.
|
|
3
|
-
dbos-0.
|
|
4
|
-
dbos-0.
|
|
1
|
+
dbos-0.24.0a1.dist-info/METADATA,sha256=UuArfBoytGeWjufDI1gg6odzVSbkLTCGu_ZYtZFe_uM,5555
|
|
2
|
+
dbos-0.24.0a1.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
|
|
3
|
+
dbos-0.24.0a1.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
|
|
4
|
+
dbos-0.24.0a1.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
|
|
@@ -40,12 +40,12 @@ dbos/_recovery.py,sha256=4KyZb0XJEUGH7ekYT1kpx38i6y5vygPeH75Ta7RZjYo,2596
|
|
|
40
40
|
dbos/_registrations.py,sha256=_zy6k944Ll8QwqU12Kr3OP23ukVtm8axPNN1TS_kJRc,6717
|
|
41
41
|
dbos/_request.py,sha256=cX1B3Atlh160phgS35gF1VEEV4pD126c9F3BDgBmxZU,929
|
|
42
42
|
dbos/_roles.py,sha256=iOsgmIAf1XVzxs3gYWdGRe1B880YfOw5fpU7Jwx8_A8,2271
|
|
43
|
-
dbos/_scheduler.py,sha256=
|
|
43
|
+
dbos/_scheduler.py,sha256=boG4BdcncFa3WxR97T5Oou4ppR0TgrEa2QQkjzpFEHU,2028
|
|
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=qzVPkg64fvTwDGOI_ATQ4JySiH6szyo6NmRrZaCeDwQ,64674
|
|
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.
|
|
68
|
+
dbos-0.24.0a1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|