dbos 1.2.0a2__py3-none-any.whl → 1.2.0a4__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/_dbos.py +0 -2
- dbos/_dbos_config.py +0 -23
- dbos/_queue.py +3 -0
- dbos/_sys_db.py +37 -49
- {dbos-1.2.0a2.dist-info → dbos-1.2.0a4.dist-info}/METADATA +1 -1
- {dbos-1.2.0a2.dist-info → dbos-1.2.0a4.dist-info}/RECORD +9 -9
- {dbos-1.2.0a2.dist-info → dbos-1.2.0a4.dist-info}/WHEEL +0 -0
- {dbos-1.2.0a2.dist-info → dbos-1.2.0a4.dist-info}/entry_points.txt +0 -0
- {dbos-1.2.0a2.dist-info → dbos-1.2.0a4.dist-info}/licenses/LICENSE +0 -0
dbos/_dbos.py
CHANGED
@@ -90,7 +90,6 @@ from ._context import (
|
|
90
90
|
from ._dbos_config import (
|
91
91
|
ConfigFile,
|
92
92
|
DBOSConfig,
|
93
|
-
check_config_consistency,
|
94
93
|
overwrite_config,
|
95
94
|
process_config,
|
96
95
|
set_env_vars,
|
@@ -324,7 +323,6 @@ class DBOS:
|
|
324
323
|
unvalidated_config = translate_dbos_config_to_config_file(config)
|
325
324
|
if os.environ.get("DBOS__CLOUD") == "true":
|
326
325
|
unvalidated_config = overwrite_config(unvalidated_config)
|
327
|
-
check_config_consistency(name=unvalidated_config["name"])
|
328
326
|
|
329
327
|
if unvalidated_config is not None:
|
330
328
|
self._config: ConfigFile = process_config(data=unvalidated_config)
|
dbos/_dbos_config.py
CHANGED
@@ -529,26 +529,3 @@ def overwrite_config(provided_config: ConfigFile) -> ConfigFile:
|
|
529
529
|
del provided_config["env"]
|
530
530
|
|
531
531
|
return provided_config
|
532
|
-
|
533
|
-
|
534
|
-
def check_config_consistency(
|
535
|
-
*,
|
536
|
-
name: str,
|
537
|
-
config_file_path: str = DBOS_CONFIG_PATH,
|
538
|
-
) -> None:
|
539
|
-
# First load the config file and check whether it is present
|
540
|
-
try:
|
541
|
-
config = load_config(config_file_path, silent=True, run_process_config=False)
|
542
|
-
except FileNotFoundError:
|
543
|
-
dbos_logger.debug(
|
544
|
-
f"No configuration file {config_file_path} found. Skipping consistency check with provided config."
|
545
|
-
)
|
546
|
-
return
|
547
|
-
except Exception as e:
|
548
|
-
raise e
|
549
|
-
|
550
|
-
# Check the name
|
551
|
-
if name != config["name"]:
|
552
|
-
raise DBOSInitializationError(
|
553
|
-
f"Provided app name '{name}' does not match the app name '{config['name']}' in {config_file_path}."
|
554
|
-
)
|
dbos/_queue.py
CHANGED
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Any, Callable, Coroutine, Optional, TypedDict
|
|
5
5
|
from psycopg import errors
|
6
6
|
from sqlalchemy.exc import OperationalError
|
7
7
|
|
8
|
+
from dbos._logger import dbos_logger
|
8
9
|
from dbos._utils import GlobalParams
|
9
10
|
|
10
11
|
from ._core import P, R, execute_workflow_by_id, start_workflow, start_workflow_async
|
@@ -56,6 +57,8 @@ class Queue:
|
|
56
57
|
from ._dbos import _get_or_create_dbos_registry
|
57
58
|
|
58
59
|
registry = _get_or_create_dbos_registry()
|
60
|
+
if self.name in registry.queue_info_map:
|
61
|
+
dbos_logger.warning(f"Queue {name} has already been declared")
|
59
62
|
registry.queue_info_map[self.name] = self
|
60
63
|
|
61
64
|
def enqueue(
|
dbos/_sys_db.py
CHANGED
@@ -1710,13 +1710,8 @@ class SystemDatabase:
|
|
1710
1710
|
if num_recent_queries >= queue.limiter["limit"]:
|
1711
1711
|
return []
|
1712
1712
|
|
1713
|
-
#
|
1714
|
-
|
1715
|
-
# functions, else select all of them.
|
1716
|
-
|
1717
|
-
# First lets figure out how many tasks are eligible for dequeue.
|
1718
|
-
# This means figuring out how many unstarted tasks are within the local and global concurrency limits
|
1719
|
-
running_tasks_query = (
|
1713
|
+
# Count how many workflows on this queue are currently PENDING both locally and globally.
|
1714
|
+
pending_tasks_query = (
|
1720
1715
|
sa.select(
|
1721
1716
|
SystemSchema.workflow_status.c.executor_id,
|
1722
1717
|
sa.func.count().label("task_count"),
|
@@ -1730,41 +1725,37 @@ class SystemDatabase:
|
|
1730
1725
|
)
|
1731
1726
|
.where(SystemSchema.workflow_queue.c.queue_name == queue.name)
|
1732
1727
|
.where(
|
1733
|
-
SystemSchema.
|
1734
|
-
|
1735
|
-
) # Task is started
|
1736
|
-
)
|
1737
|
-
.where(
|
1738
|
-
SystemSchema.workflow_queue.c.completed_at_epoch_ms.is_(
|
1739
|
-
None
|
1740
|
-
) # Task is not completed.
|
1728
|
+
SystemSchema.workflow_status.c.status
|
1729
|
+
== WorkflowStatusString.PENDING.value
|
1741
1730
|
)
|
1742
1731
|
.group_by(SystemSchema.workflow_status.c.executor_id)
|
1743
1732
|
)
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
executor_id, 0
|
1748
|
-
) # Get count for current executor
|
1733
|
+
pending_workflows = c.execute(pending_tasks_query).fetchall()
|
1734
|
+
pending_workflows_dict = {row[0]: row[1] for row in pending_workflows}
|
1735
|
+
local_pending_workflows = pending_workflows_dict.get(executor_id, 0)
|
1749
1736
|
|
1737
|
+
# Compute max_tasks, the number of workflows that can be dequeued given local and global concurrency limits,
|
1750
1738
|
max_tasks = float("inf")
|
1751
1739
|
if queue.worker_concurrency is not None:
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1740
|
+
# Print a warning if the local concurrency limit is violated
|
1741
|
+
if local_pending_workflows > queue.worker_concurrency:
|
1742
|
+
dbos_logger.warning(
|
1743
|
+
f"The number of local pending workflows ({local_pending_workflows}) on queue {queue.name} exceeds the local concurrency limit ({queue.worker_concurrency})"
|
1744
|
+
)
|
1745
|
+
max_tasks = max(0, queue.worker_concurrency - local_pending_workflows)
|
1746
|
+
|
1755
1747
|
if queue.concurrency is not None:
|
1756
|
-
|
1757
|
-
#
|
1758
|
-
|
1759
|
-
if total_running_tasks > queue.concurrency:
|
1748
|
+
global_pending_workflows = sum(pending_workflows_dict.values())
|
1749
|
+
# Print a warning if the global concurrency limit is violated
|
1750
|
+
if global_pending_workflows > queue.concurrency:
|
1760
1751
|
dbos_logger.warning(
|
1761
|
-
f"
|
1752
|
+
f"The total number of pending workflows ({global_pending_workflows}) on queue {queue.name} exceeds the global concurrency limit ({queue.concurrency})"
|
1762
1753
|
)
|
1763
|
-
available_tasks = max(0, queue.concurrency -
|
1754
|
+
available_tasks = max(0, queue.concurrency - global_pending_workflows)
|
1764
1755
|
max_tasks = min(max_tasks, available_tasks)
|
1765
1756
|
|
1766
1757
|
# Retrieve the first max_tasks workflows in the queue.
|
1767
|
-
# Only retrieve workflows of the
|
1758
|
+
# Only retrieve workflows of the local version (or without version set)
|
1768
1759
|
query = (
|
1769
1760
|
sa.select(
|
1770
1761
|
SystemSchema.workflow_queue.c.workflow_uuid,
|
@@ -1777,8 +1768,10 @@ class SystemDatabase:
|
|
1777
1768
|
)
|
1778
1769
|
)
|
1779
1770
|
.where(SystemSchema.workflow_queue.c.queue_name == queue.name)
|
1780
|
-
.where(
|
1781
|
-
|
1771
|
+
.where(
|
1772
|
+
SystemSchema.workflow_status.c.status
|
1773
|
+
== WorkflowStatusString.ENQUEUED.value
|
1774
|
+
)
|
1782
1775
|
.where(
|
1783
1776
|
sa.or_(
|
1784
1777
|
SystemSchema.workflow_status.c.application_version
|
@@ -1807,20 +1800,16 @@ class SystemDatabase:
|
|
1807
1800
|
ret_ids: list[str] = []
|
1808
1801
|
|
1809
1802
|
for id in dequeued_ids:
|
1810
|
-
# If we have a limiter, stop
|
1811
|
-
# of
|
1803
|
+
# If we have a limiter, stop dequeueing workflows when the number
|
1804
|
+
# of workflows started this period exceeds the limit.
|
1812
1805
|
if queue.limiter is not None:
|
1813
1806
|
if len(ret_ids) + num_recent_queries >= queue.limiter["limit"]:
|
1814
1807
|
break
|
1815
1808
|
|
1816
|
-
# To start a
|
1817
|
-
|
1809
|
+
# To start a workflow, first set its status to PENDING and update its executor ID
|
1810
|
+
c.execute(
|
1818
1811
|
SystemSchema.workflow_status.update()
|
1819
1812
|
.where(SystemSchema.workflow_status.c.workflow_uuid == id)
|
1820
|
-
.where(
|
1821
|
-
SystemSchema.workflow_status.c.status
|
1822
|
-
== WorkflowStatusString.ENQUEUED.value
|
1823
|
-
)
|
1824
1813
|
.values(
|
1825
1814
|
status=WorkflowStatusString.PENDING.value,
|
1826
1815
|
application_version=app_version,
|
@@ -1843,16 +1832,15 @@ class SystemDatabase:
|
|
1843
1832
|
),
|
1844
1833
|
)
|
1845
1834
|
)
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
ret_ids.append(id)
|
1835
|
+
# Then give it a start time
|
1836
|
+
c.execute(
|
1837
|
+
SystemSchema.workflow_queue.update()
|
1838
|
+
.where(SystemSchema.workflow_queue.c.workflow_uuid == id)
|
1839
|
+
.values(started_at_epoch_ms=start_time_ms)
|
1840
|
+
)
|
1841
|
+
ret_ids.append(id)
|
1854
1842
|
|
1855
|
-
# If we have a limiter, garbage-collect all completed
|
1843
|
+
# If we have a limiter, garbage-collect all completed workflows started
|
1856
1844
|
# before the period. If there's no limiter, there's no need--they were
|
1857
1845
|
# deleted on completion.
|
1858
1846
|
if queue.limiter is not None:
|
@@ -1,7 +1,7 @@
|
|
1
|
-
dbos-1.2.
|
2
|
-
dbos-1.2.
|
3
|
-
dbos-1.2.
|
4
|
-
dbos-1.2.
|
1
|
+
dbos-1.2.0a4.dist-info/METADATA,sha256=Tx0t3cKXZZ4AFcoCMceTSlObY86rhSLkxAedOQw5V6c,13267
|
2
|
+
dbos-1.2.0a4.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
dbos-1.2.0a4.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
|
4
|
+
dbos-1.2.0a4.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
|
@@ -13,8 +13,8 @@ dbos/_conductor/protocol.py,sha256=wgOFZxmS81bv0WCB9dAyg0s6QzldpzVKQDoSPeaX0Ws,6
|
|
13
13
|
dbos/_context.py,sha256=5ajoWAmToAfzzmMLylnJZoL4Ny9rBwZWuG05sXadMIA,24798
|
14
14
|
dbos/_core.py,sha256=7ukQH_KClBaMFy0sVTSR5tWylW-RqI9qaReBY-LDKrk,48316
|
15
15
|
dbos/_croniter.py,sha256=XHAyUyibs_59sJQfSNWkP7rqQY6_XrlfuuCxk4jYqek,47559
|
16
|
-
dbos/_dbos.py,sha256=
|
17
|
-
dbos/_dbos_config.py,sha256=
|
16
|
+
dbos/_dbos.py,sha256=1EhH7r6v2vwW3Z74nK6_Zw8InE1jSXedEsztz0I4ggA,47269
|
17
|
+
dbos/_dbos_config.py,sha256=BFL2ol4nrqOPEiu1Dj-Nk3HRiVih0DecOgCdMyENOSQ,20233
|
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
|
@@ -38,7 +38,7 @@ dbos/_migrations/versions/d76646551a6c_workflow_queue.py,sha256=G942nophZ2uC2vc4
|
|
38
38
|
dbos/_migrations/versions/eab0cc1d9a14_job_queue.py,sha256=uvhFOtqbBreCePhAxZfIT0qCAI7BiZTou9wt6QnbY7c,1412
|
39
39
|
dbos/_migrations/versions/f4b9b32ba814_functionname_childid_op_outputs.py,sha256=m90Lc5YH0ZISSq1MyxND6oq3RZrZKrIqEsZtwJ1jWxA,1049
|
40
40
|
dbos/_outcome.py,sha256=EXxBg4jXCVJsByDQ1VOCIedmbeq_03S6d-p1vqQrLFU,6810
|
41
|
-
dbos/_queue.py,sha256=
|
41
|
+
dbos/_queue.py,sha256=6cmqB1DoCJUh-y7DetneZRrL5jM5mw0xG9qj7jPu8EE,3687
|
42
42
|
dbos/_recovery.py,sha256=jVMexjfCCNopzyn8gVQzJCmGJaP9G3C1EFaoCQ_Nh7g,2564
|
43
43
|
dbos/_registrations.py,sha256=CZt1ElqDjCT7hz6iyT-1av76Yu-iuwu_c9lozO87wvM,7303
|
44
44
|
dbos/_roles.py,sha256=iOsgmIAf1XVzxs3gYWdGRe1B880YfOw5fpU7Jwx8_A8,2271
|
@@ -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=3Z0L72bOgHnusK1hBaETWU9RfiLBP0QnS-fdu41i0yY,5835
|
49
49
|
dbos/_serialization.py,sha256=bWuwhXSQcGmiazvhJHA5gwhrRWxtmFmcCFQSDJnqqkU,3666
|
50
|
-
dbos/_sys_db.py,sha256=
|
50
|
+
dbos/_sys_db.py,sha256=BZdUrFHG8Ze77hIuxwHpsnE--6UymjjhlH7cA3yP_-0,83230
|
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.dbos,sha256=aQnBPSSQpkB8ERfhf7gB7P9tsU6OPKhZscfeh0yiaD8,2702
|
@@ -67,4 +67,4 @@ dbos/cli/cli.py,sha256=HinoCGrAUTiSeq7AAoCFfhdiE0uDw7vLMuDMN1_YTLI,20705
|
|
67
67
|
dbos/dbos-config.schema.json,sha256=CjaspeYmOkx6Ip_pcxtmfXJTn_YGdSx_0pcPBF7KZmo,6060
|
68
68
|
dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
|
69
69
|
version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
|
70
|
-
dbos-1.2.
|
70
|
+
dbos-1.2.0a4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|