Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.

Commit fccbba9

Browse files
committed
chore: remove session pool and only use multiplexed sessions
1 parent 3b1792a commit fccbba9

18 files changed

+287
-2324
lines changed

google/cloud/spanner_dbapi/connection.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,6 @@ def __init__(self, instance, database=None, read_only=False, **kwargs):
104104

105105
self.is_closed = False
106106
self._autocommit = False
107-
# indicator to know if the session pool used by
108-
# this connection should be cleared on the
109-
# connection close
110-
self._own_pool = True
111107
self._read_only = read_only
112108
self._staleness = None
113109
self.request_priority = None
@@ -443,9 +439,6 @@ def close(self):
443439
if self._spanner_transaction_started and not self._read_only:
444440
self._transaction.rollback()
445441

446-
if self._own_pool and self.database:
447-
self.database._sessions_manager._pool.clear()
448-
449442
self.is_closed = True
450443

451444
@check_not_closed
@@ -830,7 +823,5 @@ def connect(
830823
database_id, pool=pool, database_role=database_role, logger=logger
831824
)
832825
conn = Connection(instance, database, **kwargs)
833-
if pool is not None:
834-
conn._own_pool = False
835826

836827
return conn

google/cloud/spanner_v1/database.py

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
from google.cloud.spanner_v1.batch import MutationGroups
6161
from google.cloud.spanner_v1.keyset import KeySet
6262
from google.cloud.spanner_v1.merged_result_set import MergedResultSet
63-
from google.cloud.spanner_v1.pool import BurstyPool
6463
from google.cloud.spanner_v1.session import Session
6564
from google.cloud.spanner_v1.database_sessions_manager import (
6665
DatabaseSessionsManager,
@@ -122,9 +121,11 @@ class Database(object):
122121
123122
:type pool: concrete subclass of
124123
:class:`~google.cloud.spanner_v1.pool.AbstractSessionPool`.
125-
:param pool: (Optional) session pool to be used by database. If not
126-
passed, the database will construct an instance of
127-
:class:`~google.cloud.spanner_v1.pool.BurstyPool`.
124+
:param pool: (Deprecated) session pool to be used by database. Session
125+
pools are deprecated as multiplexed sessions are now used for
126+
all operations by default. If not passed, the database will
127+
construct an internal pool instance for backward compatibility.
128+
New code should not pass a pool argument.
128129
129130
:type logger: :class:`logging.Logger`
130131
:param logger: (Optional) a custom logger that is used if `log_commit_stats`
@@ -198,16 +199,21 @@ def __init__(
198199
self._proto_descriptors = proto_descriptors
199200
self._channel_id = 0 # It'll be created when _spanner_api is created.
200201

201-
if pool is None:
202-
pool = BurstyPool(database_role=database_role)
202+
# Session pools are deprecated. Multiplexed sessions are now used for all operations.
203+
# The pool parameter is kept for backward compatibility but is ignored.
204+
if pool is not None:
205+
from warnings import warn
206+
207+
warn(
208+
"The 'pool' parameter is deprecated and ignored. "
209+
"Multiplexed sessions are now used for all operations.",
210+
DeprecationWarning,
211+
stacklevel=2,
212+
)
203213

204-
self._pool = pool
205-
pool.bind(self)
206214
is_experimental_host = self._instance.experimental_host is not None
207215

208-
self._sessions_manager = DatabaseSessionsManager(
209-
self, pool, is_experimental_host
210-
)
216+
self._sessions_manager = DatabaseSessionsManager(self, is_experimental_host)
211217

212218
@classmethod
213219
def from_pb(cls, database_pb, instance, pool=None):
@@ -861,13 +867,9 @@ def session(self, labels=None, database_role=None):
861867
# If role is specified in param, then that role is used
862868
# instead.
863869
role = database_role or self._database_role
864-
is_multiplexed = False
865-
if self.sessions_manager._use_multiplexed(
866-
transaction_type=TransactionType.READ_ONLY
867-
):
868-
is_multiplexed = True
870+
# Always use multiplexed sessions
869871
return Session(
870-
self, labels=labels, database_role=role, is_multiplexed=is_multiplexed
872+
self, labels=labels, database_role=role, is_multiplexed=True
871873
)
872874

873875
def snapshot(self, **kw):
@@ -1430,12 +1432,6 @@ def __enter__(self):
14301432

14311433
def __exit__(self, exc_type, exc_val, exc_tb):
14321434
"""End ``with`` block."""
1433-
if isinstance(exc_val, NotFound):
1434-
# If NotFound exception occurs inside the with block
1435-
# then we validate if the session still exists.
1436-
if not self._session.exists():
1437-
self._session = self._database._pool._new_session()
1438-
self._session.create()
14391435
self._database.sessions_manager.put_session(self._session)
14401436

14411437

@@ -1471,12 +1467,6 @@ def __enter__(self):
14711467

14721468
def __exit__(self, exc_type, exc_val, exc_tb):
14731469
"""End ``with`` block."""
1474-
if isinstance(exc_val, NotFound):
1475-
# If NotFound exception occurs inside the with block
1476-
# then we validate if the session still exists.
1477-
if not self._session.exists():
1478-
self._session = self._database._pool._new_session()
1479-
self._session.create()
14801470
self._database.sessions_manager.put_session(self._session)
14811471

14821472

google/cloud/spanner_v1/database_sessions_manager.py

Lines changed: 15 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
from enum import Enum
15-
from os import getenv
1615
from datetime import timedelta
1716
from threading import Event, Lock, Thread
1817
from time import sleep, time
@@ -41,31 +40,21 @@ class DatabaseSessionsManager(object):
4140
transaction type using :meth:`get_session`, and returned to the session manager
4241
using :meth:`put_session`.
4342
44-
The sessions returned by the session manager depend on the configured environment variables
45-
and the provided session pool (see :class:`~google.cloud.spanner_v1.pool.AbstractSessionPool`).
43+
Multiplexed sessions are used for all transaction types.
4644
4745
:type database: :class:`~google.cloud.spanner_v1.database.Database`
4846
:param database: The database to manage sessions for.
4947
50-
:type pool: :class:`~google.cloud.spanner_v1.pool.AbstractSessionPool`
51-
:param pool: The pool to get non-multiplexed sessions from.
48+
:type is_experimental_host: bool
49+
:param is_experimental_host: Whether the database is using an experimental host.
5250
"""
5351

54-
# Environment variables for multiplexed sessions
55-
_ENV_VAR_MULTIPLEXED = "GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS"
56-
_ENV_VAR_MULTIPLEXED_PARTITIONED = (
57-
"GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_PARTITIONED_OPS"
58-
)
59-
_ENV_VAR_MULTIPLEXED_READ_WRITE = "GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_FOR_RW"
60-
6152
# Intervals for the maintenance thread to check and refresh the multiplexed session.
6253
_MAINTENANCE_THREAD_POLLING_INTERVAL = timedelta(minutes=10)
6354
_MAINTENANCE_THREAD_REFRESH_INTERVAL = timedelta(days=7)
6455

65-
def __init__(self, database, pool, is_experimental_host: bool = False):
56+
def __init__(self, database, is_experimental_host: bool = False):
6657
self._database = database
67-
self._pool = pool
68-
self._is_experimental_host = is_experimental_host
6958

7059
# Declare multiplexed session attributes. When a multiplexed session for the
7160
# database session manager is created, a maintenance thread is initialized to
@@ -81,17 +70,16 @@ def __init__(self, database, pool, is_experimental_host: bool = False):
8170
self._multiplexed_session_terminate_event: Event = Event()
8271

8372
def get_session(self, transaction_type: TransactionType) -> Session:
84-
"""Returns a session for the given transaction type from the database session manager.
73+
"""Returns a multiplexed session for the given transaction type.
74+
75+
:type transaction_type: :class:`TransactionType`
76+
:param transaction_type: The type of transaction (ignored, multiplexed
77+
sessions support all transaction types).
8578
8679
:rtype: :class:`~google.cloud.spanner_v1.session.Session`
87-
:returns: a session for the given transaction type.
80+
:returns: a multiplexed session.
8881
"""
89-
90-
session = (
91-
self._get_multiplexed_session()
92-
if self._use_multiplexed(transaction_type) or self._is_experimental_host
93-
else self._pool.get()
94-
)
82+
session = self._get_multiplexed_session()
9583

9684
add_span_event(
9785
get_current_span(),
@@ -104,21 +92,18 @@ def get_session(self, transaction_type: TransactionType) -> Session:
10492
def put_session(self, session: Session) -> None:
10593
"""Returns the session to the database session manager.
10694
95+
For multiplexed sessions, this is a no-op since they can handle
96+
multiple concurrent transactions and don't need to be returned to a pool.
97+
10798
:type session: :class:`~google.cloud.spanner_v1.session.Session`
10899
:param session: The session to return to the database session manager.
109100
"""
110-
111101
add_span_event(
112102
get_current_span(),
113103
"Returning session",
114104
{"id": session.session_id, "multiplexed": session.is_multiplexed},
115105
)
116-
117-
# No action is needed for multiplexed sessions: the session
118-
# pool is only used for managing non-multiplexed sessions,
119-
# since they can only process one transaction at a time.
120-
if not session.is_multiplexed:
121-
self._pool.put(session)
106+
# Multiplexed sessions don't need to be returned to a pool
122107

123108
def _get_multiplexed_session(self) -> Session:
124109
"""Returns a multiplexed session from the database session manager.
@@ -226,53 +211,3 @@ def _maintain_multiplexed_session(session_manager_ref) -> None:
226211

227212
session_created_time = time()
228213

229-
@classmethod
230-
def _use_multiplexed(cls, transaction_type: TransactionType) -> bool:
231-
"""Returns whether to use multiplexed sessions for the given transaction type.
232-
233-
Multiplexed sessions are enabled for read-only transactions if:
234-
* _ENV_VAR_MULTIPLEXED != 'false'.
235-
236-
Multiplexed sessions are enabled for partitioned transactions if:
237-
* _ENV_VAR_MULTIPLEXED_PARTITIONED != 'false'.
238-
239-
Multiplexed sessions are enabled for read/write transactions if:
240-
* _ENV_VAR_MULTIPLEXED_READ_WRITE != 'false'.
241-
242-
:type transaction_type: :class:`TransactionType`
243-
:param transaction_type: the type of transaction
244-
245-
:rtype: bool
246-
:returns: True if multiplexed sessions should be used for the given transaction
247-
type, False otherwise.
248-
249-
:raises ValueError: if the transaction type is not supported.
250-
"""
251-
252-
if transaction_type is TransactionType.READ_ONLY:
253-
return cls._getenv(cls._ENV_VAR_MULTIPLEXED)
254-
255-
elif transaction_type is TransactionType.PARTITIONED:
256-
return cls._getenv(cls._ENV_VAR_MULTIPLEXED_PARTITIONED)
257-
258-
elif transaction_type is TransactionType.READ_WRITE:
259-
return cls._getenv(cls._ENV_VAR_MULTIPLEXED_READ_WRITE)
260-
261-
raise ValueError(f"Transaction type {transaction_type} is not supported.")
262-
263-
@classmethod
264-
def _getenv(cls, env_var_name: str) -> bool:
265-
"""Returns the value of the given environment variable as a boolean.
266-
267-
True unless explicitly 'false' (case-insensitive).
268-
All other values (including unset) are considered true.
269-
270-
:type env_var_name: str
271-
:param env_var_name: the name of the boolean environment variable
272-
273-
:rtype: bool
274-
:returns: True unless the environment variable is set to 'false', False otherwise.
275-
"""
276-
277-
env_var_value = getenv(env_var_name, "true").lower().strip()
278-
return env_var_value != "false"

google/cloud/spanner_v1/instance.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,8 @@ def database(
450450
451451
:type pool: concrete subclass of
452452
:class:`~google.cloud.spanner_v1.pool.AbstractSessionPool`.
453-
:param pool: (Optional) session pool to be used by database.
453+
:param pool: (Optional) Deprecated. Session pools are no longer used.
454+
Multiplexed sessions are now used for all operations.
454455
455456
:type logger: :class:`logging.Logger`
456457
:param logger: (Optional) a custom logger that is used if `log_commit_stats`
@@ -488,13 +489,21 @@ def database(
488489
:rtype: :class:`~google.cloud.spanner_v1.database.Database`
489490
:returns: a database owned by this instance.
490491
"""
492+
if pool is not None:
493+
from warnings import warn
494+
495+
warn(
496+
"The 'pool' parameter is deprecated and ignored. "
497+
"Multiplexed sessions are now used for all operations.",
498+
DeprecationWarning,
499+
stacklevel=2,
500+
)
491501

492502
if not enable_interceptors_in_tests:
493503
return Database(
494504
database_id,
495505
self,
496506
ddl_statements=ddl_statements,
497-
pool=pool,
498507
logger=logger,
499508
encryption_config=encryption_config,
500509
database_dialect=database_dialect,
@@ -507,7 +516,6 @@ def database(
507516
database_id,
508517
self,
509518
ddl_statements=ddl_statements,
510-
pool=pool,
511519
logger=logger,
512520
encryption_config=encryption_config,
513521
database_dialect=database_dialect,

0 commit comments

Comments
 (0)