dbos 0.23.0a14__tar.gz → 0.24.0a3__tar.gz
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-0.23.0a14 → dbos-0.24.0a3}/PKG-INFO +1 -1
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_conductor/conductor.py +22 -12
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_debug.py +7 -1
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_scheduler.py +5 -2
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_sys_db.py +5 -1
- {dbos-0.23.0a14 → dbos-0.24.0a3}/pyproject.toml +1 -1
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_debug.py +2 -2
- {dbos-0.23.0a14 → dbos-0.24.0a3}/LICENSE +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/README.md +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/__init__.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/__main__.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_admin_server.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_app_db.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_classproperty.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_cloudutils/authentication.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_cloudutils/cloudutils.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_cloudutils/databases.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_conductor/protocol.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_context.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_core.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_croniter.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_db_wizard.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_dbos.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_dbos_config.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_error.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_fastapi.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_flask.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_kafka.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_kafka_message.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_logger.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/env.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/script.py.mako +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_outcome.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_queue.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_recovery.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_registrations.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_request.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_roles.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_schemas/__init__.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_schemas/application_database.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_schemas/system_database.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_serialization.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/README.md +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/__package/main.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_tracer.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_utils.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_workflow_commands.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/cli/_github_init.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/cli/_template_init.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/cli/cli.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/dbos-config.schema.json +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/py.typed +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/__init__.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/atexit_no_ctor.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/atexit_no_launch.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/classdefs.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/conftest.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/more_classdefs.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/queuedworkflow.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_admin_server.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_async.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_classdecorators.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_concurrency.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_config.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_croniter.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_dbos.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_failures.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_fastapi.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_fastapi_roles.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_flask.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_kafka.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_outcome.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_package.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_queue.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_scheduler.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_schema_migration.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_singleton.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_spans.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_sqlalchemy.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_workflow_cancel.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/tests/test_workflow_cmds.py +0 -0
- {dbos-0.23.0a14 → dbos-0.24.0a3}/version/__init__.py +0 -0
|
@@ -3,7 +3,7 @@ import time
|
|
|
3
3
|
import traceback
|
|
4
4
|
from typing import TYPE_CHECKING, Optional
|
|
5
5
|
|
|
6
|
-
from websockets import ConnectionClosed, ConnectionClosedOK
|
|
6
|
+
from websockets import ConnectionClosed, ConnectionClosedOK, InvalidStatus
|
|
7
7
|
from websockets.sync.client import connect
|
|
8
8
|
from websockets.sync.connection import Connection
|
|
9
9
|
|
|
@@ -39,12 +39,12 @@ class ConductorWebsocket(threading.Thread):
|
|
|
39
39
|
message = websocket.recv()
|
|
40
40
|
if not isinstance(message, str):
|
|
41
41
|
self.dbos.logger.warning(
|
|
42
|
-
"
|
|
42
|
+
"Received unexpected non-str message"
|
|
43
43
|
)
|
|
44
44
|
continue
|
|
45
45
|
base_message = p.BaseMessage.from_json(message)
|
|
46
|
-
|
|
47
|
-
if
|
|
46
|
+
msg_type = base_message.type
|
|
47
|
+
if msg_type == p.MessageType.EXECUTOR_INFO:
|
|
48
48
|
info_response = p.ExecutorInfoResponse(
|
|
49
49
|
type=p.MessageType.EXECUTOR_INFO,
|
|
50
50
|
request_id=base_message.request_id,
|
|
@@ -53,7 +53,7 @@ class ConductorWebsocket(threading.Thread):
|
|
|
53
53
|
)
|
|
54
54
|
websocket.send(info_response.to_json())
|
|
55
55
|
self.dbos.logger.info("Connected to DBOS conductor")
|
|
56
|
-
elif
|
|
56
|
+
elif msg_type == p.MessageType.RECOVERY:
|
|
57
57
|
recovery_message = p.RecoveryRequest.from_json(message)
|
|
58
58
|
success = True
|
|
59
59
|
try:
|
|
@@ -71,7 +71,7 @@ class ConductorWebsocket(threading.Thread):
|
|
|
71
71
|
success=success,
|
|
72
72
|
)
|
|
73
73
|
websocket.send(recovery_response.to_json())
|
|
74
|
-
elif
|
|
74
|
+
elif msg_type == p.MessageType.CANCEL:
|
|
75
75
|
cancel_message = p.CancelRequest.from_json(message)
|
|
76
76
|
success = True
|
|
77
77
|
try:
|
|
@@ -87,7 +87,7 @@ class ConductorWebsocket(threading.Thread):
|
|
|
87
87
|
success=success,
|
|
88
88
|
)
|
|
89
89
|
websocket.send(cancel_response.to_json())
|
|
90
|
-
elif
|
|
90
|
+
elif msg_type == p.MessageType.RESUME:
|
|
91
91
|
resume_message = p.ResumeRequest.from_json(message)
|
|
92
92
|
success = True
|
|
93
93
|
try:
|
|
@@ -103,7 +103,7 @@ class ConductorWebsocket(threading.Thread):
|
|
|
103
103
|
success=success,
|
|
104
104
|
)
|
|
105
105
|
websocket.send(resume_response.to_json())
|
|
106
|
-
elif
|
|
106
|
+
elif msg_type == p.MessageType.RESTART:
|
|
107
107
|
restart_message = p.RestartRequest.from_json(message)
|
|
108
108
|
success = True
|
|
109
109
|
try:
|
|
@@ -119,7 +119,7 @@ class ConductorWebsocket(threading.Thread):
|
|
|
119
119
|
success=success,
|
|
120
120
|
)
|
|
121
121
|
websocket.send(restart_response.to_json())
|
|
122
|
-
elif
|
|
122
|
+
elif msg_type == p.MessageType.LIST_WORKFLOWS:
|
|
123
123
|
list_workflows_message = p.ListWorkflowsRequest.from_json(
|
|
124
124
|
message
|
|
125
125
|
)
|
|
@@ -147,7 +147,7 @@ class ConductorWebsocket(threading.Thread):
|
|
|
147
147
|
],
|
|
148
148
|
)
|
|
149
149
|
websocket.send(list_workflows_response.to_json())
|
|
150
|
-
elif
|
|
150
|
+
elif msg_type == p.MessageType.LIST_QUEUED_WORKFLOWS:
|
|
151
151
|
list_queued_workflows_message = (
|
|
152
152
|
p.ListQueuedWorkflowsRequest.from_json(message)
|
|
153
153
|
)
|
|
@@ -175,7 +175,7 @@ class ConductorWebsocket(threading.Thread):
|
|
|
175
175
|
)
|
|
176
176
|
)
|
|
177
177
|
websocket.send(list_queued_workflows_response.to_json())
|
|
178
|
-
elif
|
|
178
|
+
elif msg_type == p.MessageType.GET_WORKFLOW:
|
|
179
179
|
get_workflow_message = p.GetWorkflowRequest.from_json(
|
|
180
180
|
message
|
|
181
181
|
)
|
|
@@ -195,7 +195,9 @@ class ConductorWebsocket(threading.Thread):
|
|
|
195
195
|
)
|
|
196
196
|
websocket.send(get_workflow_response.to_json())
|
|
197
197
|
else:
|
|
198
|
-
self.dbos.logger.warning(
|
|
198
|
+
self.dbos.logger.warning(
|
|
199
|
+
f"Unexpected message type: {msg_type}"
|
|
200
|
+
)
|
|
199
201
|
except ConnectionClosedOK:
|
|
200
202
|
self.dbos.logger.info("Conductor connection terminated")
|
|
201
203
|
break
|
|
@@ -205,6 +207,14 @@ class ConductorWebsocket(threading.Thread):
|
|
|
205
207
|
)
|
|
206
208
|
time.sleep(1)
|
|
207
209
|
continue
|
|
210
|
+
except InvalidStatus as e:
|
|
211
|
+
# This happens when it cannot open a connection to the conductor. E.g., the conductor rejects the request
|
|
212
|
+
json_data = e.response.body.decode("utf-8")
|
|
213
|
+
self.dbos.logger.error(
|
|
214
|
+
f"Failed to connect to conductor. Retrying: {str(e) }. Details: {json_data}"
|
|
215
|
+
)
|
|
216
|
+
time.sleep(1)
|
|
217
|
+
continue
|
|
208
218
|
except Exception as e:
|
|
209
219
|
self.dbos.logger.error(
|
|
210
220
|
f"Unexpected exception in connection to conductor. Reconnecting: {e}"
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import runpy
|
|
3
3
|
import sys
|
|
4
|
+
from pathlib import Path
|
|
4
5
|
from typing import Union
|
|
5
6
|
|
|
7
|
+
from fastapi_cli.discover import get_module_data_from_path
|
|
8
|
+
|
|
6
9
|
from dbos import DBOS
|
|
7
10
|
|
|
8
11
|
|
|
@@ -33,7 +36,10 @@ def debug_workflow(workflow_id: str, entrypoint: Union[str, PythonModule]) -> No
|
|
|
33
36
|
def parse_start_command(command: str) -> Union[str, PythonModule]:
|
|
34
37
|
match = re.match(r"fastapi\s+run\s+(\.?[\w/]+\.py)", command)
|
|
35
38
|
if match:
|
|
36
|
-
|
|
39
|
+
# Mirror the logic in fastapi's run command by converting the path argument to a module
|
|
40
|
+
mod_data = get_module_data_from_path(Path(match.group(1)))
|
|
41
|
+
sys.path.insert(0, str(mod_data.extra_sys_path))
|
|
42
|
+
return PythonModule(mod_data.module_import_str)
|
|
37
43
|
match = re.match(r"python3?\s+(\.?[\w/]+\.py)", command)
|
|
38
44
|
if match:
|
|
39
45
|
return match.group(1)
|
|
@@ -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(
|
|
@@ -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
|
|
@@ -11,9 +11,9 @@ from dbos._schemas.system_database import SystemSchema
|
|
|
11
11
|
|
|
12
12
|
def test_parse_fast_api_command() -> None:
|
|
13
13
|
command = "fastapi run app/main.py"
|
|
14
|
-
expected = "app/main.py"
|
|
15
14
|
actual = parse_start_command(command)
|
|
16
|
-
assert actual
|
|
15
|
+
assert isinstance(actual, PythonModule)
|
|
16
|
+
assert actual.module_name == "main"
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def test_parse_python_command() -> None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py
RENAMED
|
File without changes
|
|
File without changes
|
{dbos-0.23.0a14 → dbos-0.24.0a3}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|