Skip to content

Commit c00fae5

Browse files
committed
Rebase
1 parent 99935fc commit c00fae5

File tree

4 files changed

+42
-8
lines changed

4 files changed

+42
-8
lines changed

UPDATING.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,41 @@ assists people when migrating to a new version.
2424

2525
## Next
2626

27+
### Engine Manager for Connection Pooling
28+
29+
A new `EngineManager` class has been introduced to centralize SQLAlchemy engine creation and management. This enables connection pooling for analytics databases and provides a more flexible architecture for engine configuration.
30+
31+
#### Breaking Changes
32+
33+
1. **Removed `SSH_TUNNEL_MANAGER_CLASS` config**: SSH tunnel handling is now integrated into the EngineManager. If you have custom SSH tunnel managers, you'll need to migrate to the new architecture.
34+
35+
2. **Removed `nullpool` parameter**: The `get_sqla_engine()` and `get_raw_connection()` methods on the `Database` model no longer accept a `nullpool` parameter. Pool configuration is now controlled through the engine manager.
36+
37+
3. **Removed `_get_sqla_engine()` method**: The private `_get_sqla_engine()` method has been removed from the `Database` model. All engine creation now goes through the `EngineManager`.
38+
39+
#### New Configuration Options
40+
41+
```python
42+
# Engine manager mode:
43+
# - EngineModes.NEW: Creates a new engine for every connection (default, original behavior)
44+
# - EngineModes.SINGLETON: Reuses engines with connection pooling
45+
from superset.engines.manager import EngineModes
46+
ENGINE_MANAGER_MODE = EngineModes.NEW
47+
48+
# Cleanup interval for abandoned locks (default: 5 minutes)
49+
from datetime import timedelta
50+
ENGINE_MANAGER_CLEANUP_INTERVAL = timedelta(minutes=5)
51+
52+
# Automatically start cleanup thread for SINGLETON mode (default: True)
53+
ENGINE_MANAGER_AUTO_START_CLEANUP = True
54+
```
55+
56+
#### Migration Guide
57+
58+
- If you were using the `nullpool` parameter, remove it from your calls
59+
- If you had a custom `SSH_TUNNEL_MANAGER_CLASS`, refactor to use the new EngineManager architecture
60+
- If you need connection pooling, set `ENGINE_MANAGER_MODE = EngineModes.SINGLETON` and configure the pool in your database's `extra` JSON field
61+
2762
### WebSocket config for GAQ with Docker
2863

2964
[35896](https://github.com/apache/superset/pull/35896) and [37624](https://github.com/apache/superset/pull/37624) updated documentation on how to run and configure Superset with Docker. Specifically for the WebSocket configuration, a new `docker/superset-websocket/config.example.json` was added to the repo, so that users could copy it to create a `docker/superset-websocket/config.json` file. The existing `docker/superset-websocket/config.json` was removed and git-ignored, so if you're using GAQ / WebSocket make sure to:

superset/engines/manager.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ def _get_engine_args(
320320
uri = make_url_safe(database.sqlalchemy_uri_decrypted)
321321

322322
extra = database.get_extra(source)
323-
kwargs = extra.get("engine_params", {})
323+
# Make a copy to avoid mutating the original extra dict
324+
kwargs = dict(extra.get("engine_params", {}))
324325

325326
# get pool class
326327
if self.mode == EngineModes.NEW or "poolclass" not in kwargs:
@@ -336,7 +337,7 @@ def _get_engine_args(
336337
kwargs["poolclass"] = pools.get(extra["poolclass"], pool.QueuePool)
337338

338339
# update URI for specific catalog/schema
339-
connect_args = extra.setdefault("connect_args", {})
340+
connect_args = dict(extra.get("connect_args", {}))
340341
uri, connect_args = database.db_engine_spec.adjust_engine_params(
341342
uri,
342343
connect_args,

tests/unit_tests/engines/manager_test.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
from unittest.mock import MagicMock, patch
2323

2424
import pytest
25-
from sqlalchemy.pool import NullPool
2625

2726
from superset.engines.manager import _LockManager, EngineManager, EngineModes
2827

@@ -51,7 +50,7 @@ def test_cleanup_removes_unused_locks(self):
5150
manager = _LockManager()
5251

5352
# Create locks
54-
lock1 = manager.get_lock("key1")
53+
_ = manager.get_lock("key1") # noqa: F841
5554
lock2 = manager.get_lock("key2")
5655

5756
# Cleanup with only key1 active
@@ -111,7 +110,7 @@ def mock_database(self):
111110
"""Create a mock database."""
112111
database = MagicMock()
113112
database.sqlalchemy_uri_decrypted = "postgresql://user:pass@localhost/test"
114-
database.get_extra.return_value = {"engine_params": {"poolclass": NullPool}}
113+
database.get_extra.return_value = {"engine_params": {}}
115114
database.get_effective_user.return_value = "test_user"
116115
database.impersonate_user = False
117116
database.update_params_from_encrypted_extra = MagicMock()
@@ -231,7 +230,7 @@ def test_ssh_tunnel_creation(self, mock_tunnel_class, engine_manager):
231230
ssh_tunnel.server_address = "ssh.example.com"
232231
ssh_tunnel.server_port = 22
233232
ssh_tunnel.username = "ssh_user"
234-
ssh_tunnel.password = "ssh_pass"
233+
ssh_tunnel.password = "ssh_pass" # noqa: S105
235234
ssh_tunnel.private_key = None
236235
ssh_tunnel.private_key_password = None
237236

@@ -266,7 +265,7 @@ def test_ssh_tunnel_recreation_when_inactive(
266265
ssh_tunnel.server_address = "ssh.example.com"
267266
ssh_tunnel.server_port = 22
268267
ssh_tunnel.username = "ssh_user"
269-
ssh_tunnel.password = "ssh_pass"
268+
ssh_tunnel.password = "ssh_pass" # noqa: S105
270269
ssh_tunnel.private_key = None
271270
ssh_tunnel.private_key_password = None
272271

tests/unit_tests/sql/execution/conftest.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ def setup_mock_raw_connection(
202202
def _raw_connection(
203203
catalog: str | None = None,
204204
schema: str | None = None,
205-
nullpool: bool = True,
206205
source: Any | None = None,
207206
):
208207
yield mock_connection

0 commit comments

Comments
 (0)