dbos 0.24.0a6__tar.gz → 0.24.0a7__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.24.0a6 → dbos-0.24.0a7}/PKG-INFO +1 -1
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_app_db.py +16 -2
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_dbos.py +8 -1
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_dbos_config.py +52 -10
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_sys_db.py +2 -2
- {dbos-0.24.0a6 → dbos-0.24.0a7}/pyproject.toml +1 -1
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_admin_server.py +73 -1
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_config.py +184 -8
- {dbos-0.24.0a6 → dbos-0.24.0a7}/LICENSE +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/README.md +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/__init__.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/__main__.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_admin_server.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_classproperty.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_cloudutils/authentication.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_cloudutils/cloudutils.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_cloudutils/databases.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_conductor/conductor.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_conductor/protocol.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_context.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_core.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_croniter.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_db_wizard.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_debug.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_error.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_fastapi.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_flask.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_kafka.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_kafka_message.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_logger.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/env.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/script.py.mako +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_outcome.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_queue.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_recovery.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_registrations.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_request.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_roles.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_scheduler.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_schemas/__init__.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_schemas/application_database.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_schemas/system_database.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_serialization.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/README.md +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/__package/main.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_tracer.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_utils.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/_workflow_commands.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/cli/_github_init.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/cli/_template_init.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/cli/cli.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/dbos-config.schema.json +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/dbos/py.typed +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/__init__.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/atexit_no_ctor.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/atexit_no_launch.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/classdefs.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/conftest.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/more_classdefs.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/queuedworkflow.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_async.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_classdecorators.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_concurrency.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_croniter.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_dbos.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_dbwizard.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_debug.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_failures.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_fastapi.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_fastapi_roles.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_flask.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_kafka.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_outcome.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_package.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_queue.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_scheduler.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_schema_migration.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_singleton.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_spans.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_sqlalchemy.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_workflow_cancel.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/tests/test_workflow_cmds.py +0 -0
- {dbos-0.24.0a6 → dbos-0.24.0a7}/version/__init__.py +0 -0
|
@@ -5,7 +5,7 @@ import sqlalchemy.dialects.postgresql as pg
|
|
|
5
5
|
from sqlalchemy.exc import DBAPIError
|
|
6
6
|
from sqlalchemy.orm import Session, sessionmaker
|
|
7
7
|
|
|
8
|
-
from ._dbos_config import ConfigFile
|
|
8
|
+
from ._dbos_config import ConfigFile, DatabaseConfig
|
|
9
9
|
from ._error import DBOSWorkflowConflictIDError
|
|
10
10
|
from ._schemas.application_database import ApplicationSchema
|
|
11
11
|
|
|
@@ -61,8 +61,22 @@ class ApplicationDatabase:
|
|
|
61
61
|
port=config["database"]["port"],
|
|
62
62
|
database=app_db_name,
|
|
63
63
|
)
|
|
64
|
+
|
|
65
|
+
connect_args = {}
|
|
66
|
+
if (
|
|
67
|
+
"connectionTimeoutMillis" in config["database"]
|
|
68
|
+
and config["database"]["connectionTimeoutMillis"]
|
|
69
|
+
):
|
|
70
|
+
connect_args["connect_timeout"] = int(
|
|
71
|
+
config["database"]["connectionTimeoutMillis"] / 1000
|
|
72
|
+
)
|
|
73
|
+
|
|
64
74
|
self.engine = sa.create_engine(
|
|
65
|
-
app_db_url,
|
|
75
|
+
app_db_url,
|
|
76
|
+
pool_size=config["database"]["app_db_pool_size"],
|
|
77
|
+
max_overflow=0,
|
|
78
|
+
pool_timeout=30,
|
|
79
|
+
connect_args=connect_args,
|
|
66
80
|
)
|
|
67
81
|
self.sessionmaker = sessionmaker(bind=self.engine)
|
|
68
82
|
self.debug_mode = debug_mode
|
|
@@ -457,7 +457,14 @@ class DBOS:
|
|
|
457
457
|
admin_port = self.config.get("runtimeConfig", {}).get("admin_port")
|
|
458
458
|
if admin_port is None:
|
|
459
459
|
admin_port = 3001
|
|
460
|
-
|
|
460
|
+
run_admin_server = self.config.get("runtimeConfig", {}).get(
|
|
461
|
+
"run_admin_server"
|
|
462
|
+
)
|
|
463
|
+
if run_admin_server:
|
|
464
|
+
try:
|
|
465
|
+
self._admin_server_field = AdminServer(dbos=self, port=admin_port)
|
|
466
|
+
except Exception as e:
|
|
467
|
+
dbos_logger.warning(f"Failed to start admin server: {e}")
|
|
461
468
|
|
|
462
469
|
workflow_ids = self._sys_db.get_pending_workflows(
|
|
463
470
|
GlobalParams.executor_id, GlobalParams.app_version
|
|
@@ -22,30 +22,38 @@ from ._logger import dbos_logger
|
|
|
22
22
|
DBOS_CONFIG_PATH = "dbos-config.yaml"
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class DBOSConfig(TypedDict):
|
|
25
|
+
class DBOSConfig(TypedDict, total=False):
|
|
26
26
|
"""
|
|
27
27
|
Data structure containing the DBOS library configuration.
|
|
28
28
|
|
|
29
29
|
Attributes:
|
|
30
30
|
name (str): Application name
|
|
31
31
|
database_url (str): Database connection string
|
|
32
|
+
app_db_pool_size (int): Application database pool size
|
|
32
33
|
sys_db_name (str): System database name
|
|
34
|
+
sys_db_pool_size (int): System database pool size
|
|
33
35
|
log_level (str): Log level
|
|
34
36
|
otlp_traces_endpoints: List[str]: OTLP traces endpoints
|
|
37
|
+
admin_port (int): Admin port
|
|
38
|
+
run_admin_server (bool): Whether to run the DBOS admin server
|
|
35
39
|
"""
|
|
36
40
|
|
|
37
41
|
name: str
|
|
38
42
|
database_url: Optional[str]
|
|
43
|
+
app_db_pool_size: Optional[int]
|
|
39
44
|
sys_db_name: Optional[str]
|
|
45
|
+
sys_db_pool_size: Optional[int]
|
|
40
46
|
log_level: Optional[str]
|
|
41
47
|
otlp_traces_endpoints: Optional[List[str]]
|
|
42
48
|
admin_port: Optional[int]
|
|
49
|
+
run_admin_server: Optional[bool]
|
|
43
50
|
|
|
44
51
|
|
|
45
52
|
class RuntimeConfig(TypedDict, total=False):
|
|
46
53
|
start: List[str]
|
|
47
54
|
setup: Optional[List[str]]
|
|
48
55
|
admin_port: Optional[int]
|
|
56
|
+
run_admin_server: Optional[bool]
|
|
49
57
|
|
|
50
58
|
|
|
51
59
|
class DatabaseConfig(TypedDict, total=False):
|
|
@@ -55,7 +63,9 @@ class DatabaseConfig(TypedDict, total=False):
|
|
|
55
63
|
password: str
|
|
56
64
|
connectionTimeoutMillis: Optional[int]
|
|
57
65
|
app_db_name: str
|
|
66
|
+
app_db_pool_size: Optional[int]
|
|
58
67
|
sys_db_name: Optional[str]
|
|
68
|
+
sys_db_pool_size: Optional[int]
|
|
59
69
|
ssl: Optional[bool]
|
|
60
70
|
ssl_ca: Optional[str]
|
|
61
71
|
local_suffix: Optional[bool]
|
|
@@ -160,12 +170,21 @@ def translate_dbos_config_to_config_file(config: DBOSConfig) -> ConfigFile:
|
|
|
160
170
|
db_config = parse_database_url_to_dbconfig(database_url)
|
|
161
171
|
if "sys_db_name" in config:
|
|
162
172
|
db_config["sys_db_name"] = config.get("sys_db_name")
|
|
173
|
+
if "app_db_pool_size" in config:
|
|
174
|
+
db_config["app_db_pool_size"] = config.get("app_db_pool_size")
|
|
175
|
+
if "sys_db_pool_size" in config:
|
|
176
|
+
db_config["sys_db_pool_size"] = config.get("sys_db_pool_size")
|
|
163
177
|
if db_config:
|
|
164
178
|
translated_config["database"] = db_config
|
|
165
179
|
|
|
166
|
-
#
|
|
180
|
+
# Runtime config
|
|
181
|
+
translated_config["runtimeConfig"] = {"run_admin_server": True}
|
|
167
182
|
if "admin_port" in config:
|
|
168
|
-
translated_config["runtimeConfig"]
|
|
183
|
+
translated_config["runtimeConfig"]["admin_port"] = config["admin_port"]
|
|
184
|
+
if "run_admin_server" in config:
|
|
185
|
+
translated_config["runtimeConfig"]["run_admin_server"] = config[
|
|
186
|
+
"run_admin_server"
|
|
187
|
+
]
|
|
169
188
|
|
|
170
189
|
# Telemetry config
|
|
171
190
|
telemetry = {}
|
|
@@ -289,6 +308,15 @@ def process_config(
|
|
|
289
308
|
f'Invalid app name {data["name"]}. App names must be between 3 and 30 characters long and contain only lowercase letters, numbers, dashes, and underscores.'
|
|
290
309
|
)
|
|
291
310
|
|
|
311
|
+
if data.get("telemetry") is None:
|
|
312
|
+
data["telemetry"] = {}
|
|
313
|
+
telemetry = cast(TelemetryConfig, data["telemetry"])
|
|
314
|
+
if telemetry.get("logs") is None:
|
|
315
|
+
telemetry["logs"] = {}
|
|
316
|
+
logs = cast(LoggerConfig, telemetry["logs"])
|
|
317
|
+
if logs.get("logLevel") is None:
|
|
318
|
+
logs["logLevel"] = "INFO"
|
|
319
|
+
|
|
292
320
|
if "database" not in data:
|
|
293
321
|
data["database"] = {}
|
|
294
322
|
|
|
@@ -379,6 +407,20 @@ def process_config(
|
|
|
379
407
|
local_suffix = dbos_dblocalsuffix
|
|
380
408
|
data["database"]["local_suffix"] = local_suffix
|
|
381
409
|
|
|
410
|
+
if not data["database"].get("app_db_pool_size"):
|
|
411
|
+
data["database"]["app_db_pool_size"] = 20
|
|
412
|
+
if not data["database"].get("sys_db_pool_size"):
|
|
413
|
+
data["database"]["sys_db_pool_size"] = 20
|
|
414
|
+
if not data["database"].get("connectionTimeoutMillis"):
|
|
415
|
+
data["database"]["connectionTimeoutMillis"] = 10000
|
|
416
|
+
|
|
417
|
+
if not data.get("runtimeConfig"):
|
|
418
|
+
data["runtimeConfig"] = {
|
|
419
|
+
"run_admin_server": True,
|
|
420
|
+
}
|
|
421
|
+
elif "run_admin_server" not in data["runtimeConfig"]:
|
|
422
|
+
data["runtimeConfig"]["run_admin_server"] = True
|
|
423
|
+
|
|
382
424
|
# Check the connectivity to the database and make sure it's properly configured
|
|
383
425
|
# Note, never use db wizard if the DBOS is running in debug mode (i.e. DBOS_DEBUG_WORKFLOW_ID env var is set)
|
|
384
426
|
debugWorkflowId = os.getenv("DBOS_DEBUG_WORKFLOW_ID")
|
|
@@ -475,13 +517,13 @@ def overwrite_config(provided_config: ConfigFile) -> ConfigFile:
|
|
|
475
517
|
otlp_exporter["logsEndpoint"] = logsEndpoint
|
|
476
518
|
|
|
477
519
|
# Runtime config
|
|
478
|
-
if
|
|
479
|
-
"
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
520
|
+
if "runtimeConfig" in provided_config:
|
|
521
|
+
if "admin_port" in provided_config["runtimeConfig"]:
|
|
522
|
+
del provided_config["runtimeConfig"][
|
|
523
|
+
"admin_port"
|
|
524
|
+
] # Admin port is expected to be 3001 (the default in dbos/_admin_server.py::__init__ ) by DBOS Cloud
|
|
525
|
+
if "run_admin_server" in provided_config["runtimeConfig"]:
|
|
526
|
+
del provided_config["runtimeConfig"]["run_admin_server"]
|
|
485
527
|
|
|
486
528
|
# Env should be set from the hosting provider (e.g., DBOS Cloud)
|
|
487
529
|
if "env" in provided_config:
|
|
@@ -203,8 +203,8 @@ class SystemDatabase:
|
|
|
203
203
|
# Create a connection pool for the system database
|
|
204
204
|
self.engine = sa.create_engine(
|
|
205
205
|
system_db_url,
|
|
206
|
-
pool_size=
|
|
207
|
-
max_overflow=
|
|
206
|
+
pool_size=config["database"]["sys_db_pool_size"],
|
|
207
|
+
max_overflow=0,
|
|
208
208
|
pool_timeout=30,
|
|
209
209
|
connect_args={"connect_timeout": 10},
|
|
210
210
|
)
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import socket
|
|
2
3
|
import threading
|
|
3
4
|
import time
|
|
4
5
|
import uuid
|
|
5
6
|
|
|
7
|
+
import pytest
|
|
6
8
|
import requests
|
|
7
9
|
import sqlalchemy as sa
|
|
10
|
+
from requests.exceptions import ConnectionError
|
|
8
11
|
|
|
9
12
|
# Public API
|
|
10
|
-
from dbos import DBOS, ConfigFile, Queue, SetWorkflowID, _workflow_commands
|
|
13
|
+
from dbos import DBOS, ConfigFile, DBOSConfig, Queue, SetWorkflowID, _workflow_commands
|
|
11
14
|
from dbos._schemas.system_database import SystemSchema
|
|
12
15
|
from dbos._sys_db import SystemDatabase, WorkflowStatusString
|
|
13
16
|
from dbos._utils import GlobalParams
|
|
@@ -172,6 +175,75 @@ runtimeConfig:
|
|
|
172
175
|
os.remove("dbos-config.yaml")
|
|
173
176
|
|
|
174
177
|
|
|
178
|
+
def test_disable_admin_server(cleanup_test_databases: None) -> None:
|
|
179
|
+
# Initialize singleton
|
|
180
|
+
DBOS.destroy() # In case of other tests leaving it
|
|
181
|
+
|
|
182
|
+
config: DBOSConfig = {
|
|
183
|
+
"name": "test-app",
|
|
184
|
+
"run_admin_server": False,
|
|
185
|
+
}
|
|
186
|
+
try:
|
|
187
|
+
DBOS(config=config)
|
|
188
|
+
DBOS.launch()
|
|
189
|
+
|
|
190
|
+
with pytest.raises(ConnectionError):
|
|
191
|
+
requests.get("http://localhost:3001/dbos-healthz", timeout=1)
|
|
192
|
+
finally:
|
|
193
|
+
# Clean up after the test
|
|
194
|
+
DBOS.destroy()
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def test_busy_admin_server_port_does_not_throw() -> None:
|
|
198
|
+
# Initialize singleton
|
|
199
|
+
DBOS.destroy() # In case of other tests leaving it
|
|
200
|
+
|
|
201
|
+
config: DBOSConfig = {
|
|
202
|
+
"name": "test-app",
|
|
203
|
+
}
|
|
204
|
+
server_thread = None
|
|
205
|
+
stop_event = threading.Event()
|
|
206
|
+
try:
|
|
207
|
+
|
|
208
|
+
def start_dummy_server(port: int, stop_event: threading.Event) -> None:
|
|
209
|
+
"""Starts a simple TCP server on the given port."""
|
|
210
|
+
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
211
|
+
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
212
|
+
server_socket.bind(("0.0.0.0", port))
|
|
213
|
+
server_socket.listen(1)
|
|
214
|
+
# We need to call accept for the port to be considered busy by the OS...
|
|
215
|
+
while not stop_event.is_set():
|
|
216
|
+
try:
|
|
217
|
+
server_socket.settimeout(
|
|
218
|
+
1
|
|
219
|
+
) # Timeout for accept in case the thread is stopped.
|
|
220
|
+
client_socket, _ = server_socket.accept()
|
|
221
|
+
client_socket.close()
|
|
222
|
+
except socket.timeout:
|
|
223
|
+
pass
|
|
224
|
+
server_socket.close()
|
|
225
|
+
|
|
226
|
+
port_to_block = 3001
|
|
227
|
+
server_thread = threading.Thread(
|
|
228
|
+
target=start_dummy_server, args=(port_to_block, stop_event)
|
|
229
|
+
)
|
|
230
|
+
server_thread.daemon = (
|
|
231
|
+
True # Allows the thread to be terminated when the main thread exits
|
|
232
|
+
)
|
|
233
|
+
server_thread.start()
|
|
234
|
+
|
|
235
|
+
DBOS(config=config)
|
|
236
|
+
DBOS.launch()
|
|
237
|
+
finally:
|
|
238
|
+
# Clean up after the test
|
|
239
|
+
DBOS.destroy()
|
|
240
|
+
if server_thread and server_thread.is_alive():
|
|
241
|
+
stop_event.set()
|
|
242
|
+
server_thread.join(2)
|
|
243
|
+
if server_thread.is_alive():
|
|
244
|
+
print("Warning: Server thread did not terminate gracefully.")
|
|
245
|
+
|
|
246
|
+
|
|
175
247
|
def test_admin_workflow_resume(dbos: DBOS, sys_db: SystemDatabase) -> None:
|
|
176
248
|
counter: int = 0
|
|
177
249
|
event = threading.Event()
|
|
@@ -5,6 +5,7 @@ from unittest.mock import mock_open
|
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
7
|
import pytest_mock
|
|
8
|
+
from sqlalchemy import event
|
|
8
9
|
|
|
9
10
|
# Public API
|
|
10
11
|
from dbos import DBOS, load_config
|
|
@@ -313,7 +314,9 @@ def test_process_config_full():
|
|
|
313
314
|
"password": "password",
|
|
314
315
|
"connectionTimeoutMillis": 3000,
|
|
315
316
|
"app_db_name": "example_db",
|
|
317
|
+
"app_db_pool_size": 45,
|
|
316
318
|
"sys_db_name": "sys_db",
|
|
319
|
+
"sys_db_pool_size": 27,
|
|
317
320
|
"ssl": True,
|
|
318
321
|
"ssl_ca": "ca.pem",
|
|
319
322
|
"local_suffix": False,
|
|
@@ -323,6 +326,7 @@ def test_process_config_full():
|
|
|
323
326
|
"runtimeConfig": {
|
|
324
327
|
"start": ["python3 main.py"],
|
|
325
328
|
"admin_port": 8001,
|
|
329
|
+
"run_admin_server": False,
|
|
326
330
|
"setup": ["echo 'hello'"],
|
|
327
331
|
},
|
|
328
332
|
"telemetry": {
|
|
@@ -353,8 +357,11 @@ def test_process_config_full():
|
|
|
353
357
|
assert configFile["database"]["local_suffix"] == False
|
|
354
358
|
assert configFile["database"]["migrate"] == ["alembic upgrade head"]
|
|
355
359
|
assert configFile["database"]["rollback"] == ["alembic downgrade base"]
|
|
360
|
+
assert configFile["database"]["app_db_pool_size"] == 45
|
|
361
|
+
assert configFile["database"]["sys_db_pool_size"] == 27
|
|
356
362
|
assert configFile["runtimeConfig"]["start"] == ["python3 main.py"]
|
|
357
363
|
assert configFile["runtimeConfig"]["admin_port"] == 8001
|
|
364
|
+
assert configFile["runtimeConfig"]["run_admin_server"] == False
|
|
358
365
|
assert configFile["runtimeConfig"]["setup"] == ["echo 'hello'"]
|
|
359
366
|
assert configFile["telemetry"]["logs"]["logLevel"] == "DEBUG"
|
|
360
367
|
assert configFile["telemetry"]["OTLPExporter"]["logsEndpoint"] == "thelogsendpoint"
|
|
@@ -380,8 +387,11 @@ def test_process_config_with_db_url():
|
|
|
380
387
|
assert processed_config["database"]["ssl"] == True
|
|
381
388
|
assert processed_config["database"]["ssl_ca"] == "ca.pem"
|
|
382
389
|
assert processed_config["database"]["local_suffix"] == False
|
|
390
|
+
assert processed_config["database"]["app_db_pool_size"] == 20
|
|
391
|
+
assert processed_config["database"]["sys_db_pool_size"] == 20
|
|
383
392
|
assert "rollback" not in processed_config["database"]
|
|
384
393
|
assert "migrate" not in processed_config["database"]
|
|
394
|
+
assert processed_config["runtimeConfig"]["run_admin_server"] == True
|
|
385
395
|
|
|
386
396
|
|
|
387
397
|
def test_process_config_with_db_url_taking_precedence_over_database():
|
|
@@ -413,9 +423,12 @@ def test_process_config_with_db_url_taking_precedence_over_database():
|
|
|
413
423
|
assert processed_config["database"]["migrate"] == ["alembic upgrade head"]
|
|
414
424
|
assert processed_config["database"]["rollback"] == ["alembic downgrade base"]
|
|
415
425
|
assert processed_config["database"]["local_suffix"] == True
|
|
416
|
-
assert
|
|
426
|
+
assert processed_config["database"]["app_db_pool_size"] == 20
|
|
427
|
+
assert processed_config["database"]["sys_db_pool_size"] == 20
|
|
428
|
+
assert processed_config["database"]["connectionTimeoutMillis"] == 10000
|
|
417
429
|
assert "ssl" not in processed_config["database"]
|
|
418
430
|
assert "ssl_ca" not in processed_config["database"]
|
|
431
|
+
assert processed_config["runtimeConfig"]["run_admin_server"] == True
|
|
419
432
|
|
|
420
433
|
|
|
421
434
|
# Note this exercise going through the db wizard
|
|
@@ -432,6 +445,11 @@ def test_process_config_load_defaults():
|
|
|
432
445
|
assert processed_config["database"]["password"] == os.environ.get(
|
|
433
446
|
"PGPASSWORD", "dbos"
|
|
434
447
|
)
|
|
448
|
+
assert processed_config["database"]["connectionTimeoutMillis"] == 10000
|
|
449
|
+
assert processed_config["database"]["app_db_pool_size"] == 20
|
|
450
|
+
assert processed_config["database"]["sys_db_pool_size"] == 20
|
|
451
|
+
assert processed_config["telemetry"]["logs"]["logLevel"] == "INFO"
|
|
452
|
+
assert processed_config["runtimeConfig"]["run_admin_server"] == True
|
|
435
453
|
|
|
436
454
|
|
|
437
455
|
def test_process_config_load_default_with_None_database_url():
|
|
@@ -448,6 +466,9 @@ def test_process_config_load_default_with_None_database_url():
|
|
|
448
466
|
assert processed_config["database"]["password"] == os.environ.get(
|
|
449
467
|
"PGPASSWORD", "dbos"
|
|
450
468
|
)
|
|
469
|
+
assert processed_config["database"]["connectionTimeoutMillis"] == 10000
|
|
470
|
+
assert processed_config["database"]["app_db_pool_size"] == 20
|
|
471
|
+
assert processed_config["database"]["sys_db_pool_size"] == 20
|
|
451
472
|
|
|
452
473
|
|
|
453
474
|
def test_process_config_with_None_app_db_name():
|
|
@@ -467,6 +488,9 @@ def test_process_config_with_None_app_db_name():
|
|
|
467
488
|
assert processed_config["database"]["password"] == os.environ.get(
|
|
468
489
|
"PGPASSWORD", "dbos"
|
|
469
490
|
)
|
|
491
|
+
assert processed_config["database"]["connectionTimeoutMillis"] == 10000
|
|
492
|
+
assert processed_config["database"]["app_db_pool_size"] == 20
|
|
493
|
+
assert processed_config["database"]["sys_db_pool_size"] == 20
|
|
470
494
|
|
|
471
495
|
|
|
472
496
|
def test_process_config_with_empty_app_db_name():
|
|
@@ -486,6 +510,9 @@ def test_process_config_with_empty_app_db_name():
|
|
|
486
510
|
assert processed_config["database"]["password"] == os.environ.get(
|
|
487
511
|
"PGPASSWORD", "dbos"
|
|
488
512
|
)
|
|
513
|
+
assert processed_config["database"]["connectionTimeoutMillis"] == 10000
|
|
514
|
+
assert processed_config["database"]["app_db_pool_size"] == 20
|
|
515
|
+
assert processed_config["database"]["sys_db_pool_size"] == 20
|
|
489
516
|
|
|
490
517
|
|
|
491
518
|
def test_config_missing_name():
|
|
@@ -534,6 +561,9 @@ def test_load_config_load_db_connection(mocker):
|
|
|
534
561
|
assert configFile["database"]["password"] == "password"
|
|
535
562
|
assert configFile["database"]["local_suffix"] == True
|
|
536
563
|
assert configFile["database"]["app_db_name"] == "some_app_local"
|
|
564
|
+
assert configFile["database"]["app_db_pool_size"] == 20
|
|
565
|
+
assert configFile["database"]["sys_db_pool_size"] == 20
|
|
566
|
+
assert configFile["database"]["connectionTimeoutMillis"] == 10000
|
|
537
567
|
|
|
538
568
|
|
|
539
569
|
def test_config_mixed_params():
|
|
@@ -543,6 +573,7 @@ def test_config_mixed_params():
|
|
|
543
573
|
"port": 1234,
|
|
544
574
|
"username": "some user",
|
|
545
575
|
"password": "abc123",
|
|
576
|
+
"app_db_pool_size": 3,
|
|
546
577
|
},
|
|
547
578
|
}
|
|
548
579
|
|
|
@@ -552,6 +583,9 @@ def test_config_mixed_params():
|
|
|
552
583
|
assert configFile["database"]["port"] == 1234
|
|
553
584
|
assert configFile["database"]["username"] == "some user"
|
|
554
585
|
assert configFile["database"]["password"] == "abc123"
|
|
586
|
+
assert configFile["database"]["app_db_pool_size"] == 3
|
|
587
|
+
assert configFile["database"]["sys_db_pool_size"] == 20
|
|
588
|
+
assert configFile["database"]["connectionTimeoutMillis"] == 10000
|
|
555
589
|
|
|
556
590
|
|
|
557
591
|
def test_debug_override(mocker: pytest_mock.MockFixture):
|
|
@@ -575,6 +609,9 @@ def test_debug_override(mocker: pytest_mock.MockFixture):
|
|
|
575
609
|
assert configFile["database"]["username"] == "fakeuser"
|
|
576
610
|
assert configFile["database"]["password"] == "fakepassword"
|
|
577
611
|
assert configFile["database"]["local_suffix"] == False
|
|
612
|
+
assert configFile["database"]["app_db_pool_size"] == 20
|
|
613
|
+
assert configFile["database"]["sys_db_pool_size"] == 20
|
|
614
|
+
assert configFile["database"]["connectionTimeoutMillis"] == 10000
|
|
578
615
|
|
|
579
616
|
|
|
580
617
|
def test_local_config():
|
|
@@ -600,6 +637,8 @@ def test_local_config():
|
|
|
600
637
|
assert processed_config["database"]["password"] == os.environ["PGPASSWORD"]
|
|
601
638
|
assert processed_config["database"]["app_db_name"] == "some_db_local"
|
|
602
639
|
assert processed_config["database"]["connectionTimeoutMillis"] == 3000
|
|
640
|
+
assert processed_config["database"]["app_db_pool_size"] == 20
|
|
641
|
+
assert processed_config["database"]["sys_db_pool_size"] == 20
|
|
603
642
|
|
|
604
643
|
|
|
605
644
|
def test_local_config_without_name(mocker):
|
|
@@ -624,6 +663,8 @@ def test_local_config_without_name(mocker):
|
|
|
624
663
|
assert processed_config["database"]["password"] == os.environ["PGPASSWORD"]
|
|
625
664
|
assert processed_config["database"]["app_db_name"] == "some_app_local"
|
|
626
665
|
assert processed_config["database"]["connectionTimeoutMillis"] == 3000
|
|
666
|
+
assert processed_config["database"]["app_db_pool_size"] == 20
|
|
667
|
+
assert processed_config["database"]["sys_db_pool_size"] == 20
|
|
627
668
|
|
|
628
669
|
|
|
629
670
|
####################
|
|
@@ -676,9 +717,9 @@ def test_query_parameters():
|
|
|
676
717
|
"""Test processing of various query parameters."""
|
|
677
718
|
|
|
678
719
|
# Test connect_timeout conversion
|
|
679
|
-
database_url = "postgresql://user:password@localhost:5432/dbname?connect_timeout=
|
|
720
|
+
database_url = "postgresql://user:password@localhost:5432/dbname?connect_timeout=7"
|
|
680
721
|
db_config = parse_database_url_to_dbconfig(database_url)
|
|
681
|
-
assert db_config["connectionTimeoutMillis"] ==
|
|
722
|
+
assert db_config["connectionTimeoutMillis"] == 7000
|
|
682
723
|
|
|
683
724
|
# Test sslmode=require (should set ssl=True)
|
|
684
725
|
database_url = "postgresql://user:password@localhost:5432/dbname?sslmode=require"
|
|
@@ -701,9 +742,9 @@ def test_query_parameters():
|
|
|
701
742
|
assert db_config["ssl_ca"] == "ca.pem"
|
|
702
743
|
|
|
703
744
|
# Test multiple parameters together
|
|
704
|
-
database_url = "postgresql://user:password@localhost:5432/dbname?connect_timeout=
|
|
745
|
+
database_url = "postgresql://user:password@localhost:5432/dbname?connect_timeout=8&sslmode=require&sslrootcert=ca.pem&application_name=myapp"
|
|
705
746
|
db_config = parse_database_url_to_dbconfig(database_url)
|
|
706
|
-
assert db_config["connectionTimeoutMillis"] ==
|
|
747
|
+
assert db_config["connectionTimeoutMillis"] == 8000
|
|
707
748
|
assert db_config["ssl"] == True
|
|
708
749
|
assert db_config["ssl_ca"] == "ca.pem"
|
|
709
750
|
|
|
@@ -739,10 +780,13 @@ def test_translate_dbosconfig_full_input():
|
|
|
739
780
|
config: DBOSConfig = {
|
|
740
781
|
"name": "test-app",
|
|
741
782
|
"database_url": "postgresql://user:password@localhost:5432/dbname?connect_timeout=10&sslmode=require&sslrootcert=ca.pem",
|
|
783
|
+
"app_db_pool_size": 45,
|
|
742
784
|
"sys_db_name": "sysdb",
|
|
785
|
+
"sys_db_pool_size": 27,
|
|
743
786
|
"log_level": "DEBUG",
|
|
744
787
|
"otlp_traces_endpoints": ["http://otel:7777", "notused"],
|
|
745
788
|
"admin_port": 8001,
|
|
789
|
+
"run_admin_server": False,
|
|
746
790
|
}
|
|
747
791
|
|
|
748
792
|
translated_config = translate_dbos_config_to_config_file(config)
|
|
@@ -757,6 +801,8 @@ def test_translate_dbosconfig_full_input():
|
|
|
757
801
|
assert translated_config["database"]["connectionTimeoutMillis"] == 10000
|
|
758
802
|
assert translated_config["database"]["app_db_name"] == "dbname"
|
|
759
803
|
assert translated_config["database"]["sys_db_name"] == "sysdb"
|
|
804
|
+
assert translated_config["database"]["app_db_pool_size"] == 45
|
|
805
|
+
assert translated_config["database"]["sys_db_pool_size"] == 27
|
|
760
806
|
assert "database_url" not in translated_config
|
|
761
807
|
assert translated_config["telemetry"]["logs"]["logLevel"] == "DEBUG"
|
|
762
808
|
assert (
|
|
@@ -765,6 +811,7 @@ def test_translate_dbosconfig_full_input():
|
|
|
765
811
|
)
|
|
766
812
|
assert "logsEndpoint" not in translated_config["telemetry"]["OTLPExporter"]
|
|
767
813
|
assert translated_config["runtimeConfig"]["admin_port"] == 8001
|
|
814
|
+
assert translated_config["runtimeConfig"]["run_admin_server"] == False
|
|
768
815
|
assert "start" not in translated_config["runtimeConfig"]
|
|
769
816
|
assert "setup" not in translated_config["runtimeConfig"]
|
|
770
817
|
assert "env" not in translated_config
|
|
@@ -778,9 +825,10 @@ def test_translate_dbosconfig_minimal_input():
|
|
|
778
825
|
|
|
779
826
|
assert translated_config["name"] == "test-app"
|
|
780
827
|
assert translated_config["telemetry"]["logs"]["logLevel"] == "INFO"
|
|
828
|
+
assert translated_config["runtimeConfig"]["run_admin_server"] == True
|
|
829
|
+
assert "admin_port" not in translated_config["runtimeConfig"]
|
|
781
830
|
assert "database" not in translated_config
|
|
782
831
|
assert "env" not in translated_config
|
|
783
|
-
assert "runtimeConfig" not in translated_config
|
|
784
832
|
|
|
785
833
|
|
|
786
834
|
def test_translate_dbosconfig_just_sys_db_name():
|
|
@@ -790,11 +838,66 @@ def test_translate_dbosconfig_just_sys_db_name():
|
|
|
790
838
|
}
|
|
791
839
|
translated_config = translate_dbos_config_to_config_file(config)
|
|
792
840
|
|
|
841
|
+
assert translated_config["database"]["sys_db_name"] == "sysdb"
|
|
842
|
+
assert "app_db_pool_size" not in translated_config["database"]
|
|
843
|
+
assert "sys_db_pool_size" not in translated_config["database"]
|
|
844
|
+
assert "env" not in translated_config
|
|
845
|
+
assert "admin_port" not in translated_config["runtimeConfig"]
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
def test_translate_dbosconfig_just_app_db_pool_size():
|
|
849
|
+
config: DBOSConfig = {
|
|
850
|
+
"name": "test-app",
|
|
851
|
+
"app_db_pool_size": 45,
|
|
852
|
+
}
|
|
853
|
+
translated_config = translate_dbos_config_to_config_file(config)
|
|
854
|
+
|
|
855
|
+
assert translated_config["database"]["app_db_pool_size"] == 45
|
|
856
|
+
assert "sys_db_name" not in translated_config["database"]
|
|
857
|
+
assert "sys_db_pool_size" not in translated_config["database"]
|
|
858
|
+
assert "env" not in translated_config
|
|
859
|
+
assert "admin_port" not in translated_config["runtimeConfig"]
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
def test_translate_dbosconfig_just_sys_db_pool_size():
|
|
863
|
+
config: DBOSConfig = {
|
|
864
|
+
"name": "test-app",
|
|
865
|
+
"sys_db_pool_size": 27,
|
|
866
|
+
}
|
|
867
|
+
translated_config = translate_dbos_config_to_config_file(config)
|
|
868
|
+
|
|
869
|
+
assert translated_config["database"]["sys_db_pool_size"] == 27
|
|
870
|
+
assert "app_db_pool_size" not in translated_config["database"]
|
|
871
|
+
assert "sys_db_name" not in translated_config["database"]
|
|
872
|
+
assert "env" not in translated_config
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
def test_translate_dbosconfig_just_admin_port():
|
|
876
|
+
config: DBOSConfig = {
|
|
877
|
+
"name": "test-app",
|
|
878
|
+
"admin_port": 8001,
|
|
879
|
+
}
|
|
880
|
+
translated_config = translate_dbos_config_to_config_file(config)
|
|
881
|
+
|
|
882
|
+
assert translated_config["runtimeConfig"]["admin_port"] == 8001
|
|
883
|
+
assert translated_config["runtimeConfig"]["run_admin_server"] == True
|
|
884
|
+
assert "env" not in translated_config
|
|
885
|
+
assert "database" not in translated_config
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
def test_translate_dbosconfig_just_run_admin_server():
|
|
889
|
+
config: DBOSConfig = {
|
|
890
|
+
"name": "test-app",
|
|
891
|
+
"run_admin_server": True,
|
|
892
|
+
}
|
|
893
|
+
translated_config = translate_dbos_config_to_config_file(config)
|
|
894
|
+
|
|
793
895
|
assert translated_config["name"] == "test-app"
|
|
794
896
|
assert translated_config["telemetry"]["logs"]["logLevel"] == "INFO"
|
|
795
|
-
assert translated_config["
|
|
897
|
+
assert translated_config["runtimeConfig"]["run_admin_server"] == True
|
|
898
|
+
assert "admin_port" not in translated_config["runtimeConfig"]
|
|
796
899
|
assert "env" not in translated_config
|
|
797
|
-
assert "
|
|
900
|
+
assert "database" not in translated_config
|
|
798
901
|
|
|
799
902
|
|
|
800
903
|
def test_translate_empty_otlp_traces_endpoints():
|
|
@@ -875,6 +978,7 @@ def test_overwrite_config(mocker):
|
|
|
875
978
|
"app_db_name": "dbostestpy",
|
|
876
979
|
"sys_db_name": "sysdb",
|
|
877
980
|
"connectionTimeoutMillis": 10000,
|
|
981
|
+
"app_db_pool_size": 10,
|
|
878
982
|
},
|
|
879
983
|
"telemetry": {
|
|
880
984
|
"OTLPExporter": {
|
|
@@ -887,6 +991,7 @@ def test_overwrite_config(mocker):
|
|
|
887
991
|
},
|
|
888
992
|
"runtimeConfig": {
|
|
889
993
|
"admin_port": 8001,
|
|
994
|
+
"run_admin_server": True,
|
|
890
995
|
},
|
|
891
996
|
"env": {
|
|
892
997
|
"FOO": "BAR",
|
|
@@ -904,10 +1009,13 @@ def test_overwrite_config(mocker):
|
|
|
904
1009
|
assert config["database"]["ssl"] == True
|
|
905
1010
|
assert config["database"]["ssl_ca"] == "cert.pem"
|
|
906
1011
|
assert config["database"]["connectionTimeoutMillis"] == 10000
|
|
1012
|
+
assert config["database"]["app_db_pool_size"] == 10
|
|
1013
|
+
assert "sys_db_pool_size" not in config["database"]
|
|
907
1014
|
assert config["telemetry"]["logs"]["logLevel"] == "DEBUG"
|
|
908
1015
|
assert config["telemetry"]["OTLPExporter"]["tracesEndpoint"] == "thetracesendpoint"
|
|
909
1016
|
assert config["telemetry"]["OTLPExporter"]["logsEndpoint"] == "thelogsendpoint"
|
|
910
1017
|
assert "admin_port" not in config["runtimeConfig"]
|
|
1018
|
+
assert "run_admin_server" not in config["runtimeConfig"]
|
|
911
1019
|
assert "env" not in config
|
|
912
1020
|
|
|
913
1021
|
|
|
@@ -1185,3 +1293,71 @@ def test_name_does_no_match(mocker):
|
|
|
1185
1293
|
def test_no_config_file():
|
|
1186
1294
|
# Handles FileNotFoundError
|
|
1187
1295
|
check_config_consistency(name="stock-prices")
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
####################
|
|
1299
|
+
# DATABASES CONNECTION POOLS
|
|
1300
|
+
####################
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
def test_configured_pool_sizes():
|
|
1304
|
+
config: DBOSConfig = {
|
|
1305
|
+
"name": "test-app",
|
|
1306
|
+
"app_db_pool_size": 42,
|
|
1307
|
+
"sys_db_pool_size": 43,
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
dbos = DBOS(config=config)
|
|
1311
|
+
dbos.launch()
|
|
1312
|
+
assert dbos._app_db.engine.pool._pool.maxsize == 42
|
|
1313
|
+
assert dbos._sys_db.engine.pool._pool.maxsize == 43
|
|
1314
|
+
dbos.destroy()
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
def test_default_pool_params():
|
|
1318
|
+
config: DBOSConfig = {
|
|
1319
|
+
"name": "test-app",
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
dbos = DBOS(config=config)
|
|
1323
|
+
dbos.launch()
|
|
1324
|
+
app_db_engine = dbos._app_db.engine
|
|
1325
|
+
assert app_db_engine.pool._pool.maxsize == 20
|
|
1326
|
+
|
|
1327
|
+
# force the release of connections so we can intercept on connect.
|
|
1328
|
+
app_db_engine.dispose()
|
|
1329
|
+
|
|
1330
|
+
@event.listens_for(app_db_engine, "connect")
|
|
1331
|
+
def inspect_connection(dbapi_connection, connection_record):
|
|
1332
|
+
connect_timeout = dbapi_connection.info.get_parameters()["connect_timeout"]
|
|
1333
|
+
assert connect_timeout == "10"
|
|
1334
|
+
|
|
1335
|
+
with app_db_engine.connect() as conn:
|
|
1336
|
+
pass
|
|
1337
|
+
|
|
1338
|
+
assert dbos._sys_db.engine.pool._pool.maxsize == 20
|
|
1339
|
+
dbos.destroy()
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
def test_configured_app_db_connect_timeout():
|
|
1343
|
+
config: DBOSConfig = {
|
|
1344
|
+
"name": "test-app",
|
|
1345
|
+
"database_url": f"postgresql://postgres:@localhost:5432/dbname?connect_timeout=7",
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
dbos = DBOS(config=config)
|
|
1349
|
+
dbos.launch()
|
|
1350
|
+
app_db_engine = dbos._app_db.engine
|
|
1351
|
+
|
|
1352
|
+
# force the release of connections so we can intercept on connect.
|
|
1353
|
+
app_db_engine.dispose()
|
|
1354
|
+
|
|
1355
|
+
@event.listens_for(app_db_engine, "connect")
|
|
1356
|
+
def inspect_connection(dbapi_connection, connection_record):
|
|
1357
|
+
connect_timeout = dbapi_connection.info.get_parameters()["connect_timeout"]
|
|
1358
|
+
assert connect_timeout == "7"
|
|
1359
|
+
|
|
1360
|
+
with app_db_engine.connect() as conn:
|
|
1361
|
+
pass
|
|
1362
|
+
|
|
1363
|
+
dbos.destroy()
|
|
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.24.0a6 → dbos-0.24.0a7}/dbos/_migrations/versions/5c361fc04708_added_system_tables.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|