Skip to content

Commit d6dd35a

Browse files
committed
remove backoff state
1 parent d267eb4 commit d6dd35a

File tree

2 files changed

+18
-70
lines changed

2 files changed

+18
-70
lines changed

pymongo/asynchronous/pool.py

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from bson import DEFAULT_CODEC_OPTIONS
3838
from pymongo import _csot, helpers_shared
3939
from pymongo.asynchronous.client_session import _validate_session_write_concern
40-
from pymongo.asynchronous.helpers import _backoff, _handle_reauth
40+
from pymongo.asynchronous.helpers import _handle_reauth
4141
from pymongo.asynchronous.network import command
4242
from pymongo.common import (
4343
MAX_BSON_SIZE,
@@ -790,7 +790,6 @@ def __init__(
790790
self._max_connecting_cond = _async_create_condition(self.lock)
791791
self._pending = 0
792792
self._client_id = client_id
793-
self._backoff = 0
794793
if self.enabled_for_cmap:
795794
assert self.opts._event_listeners is not None
796795
self.opts._event_listeners.publish_pool_created(
@@ -846,8 +845,6 @@ async def _reset(
846845
async with self.size_cond:
847846
if self.closed:
848847
return
849-
# Clear the backoff state.
850-
self._backoff = 0
851848
if self.opts.pause_enabled and pause and not self.opts.load_balanced:
852849
old_state, self.state = self.state, PoolState.PAUSED
853850
self.gen.inc(service_id)
@@ -930,11 +927,6 @@ async def _reset(
930927
for conn in sockets:
931928
await conn.close_conn(ConnectionClosedReason.STALE)
932929

933-
@property
934-
def max_connecting(self) -> int:
935-
"""The current max connecting limit for the pool."""
936-
return 1 if self._backoff else self.opts.max_connecting
937-
938930
async def update_is_writable(self, is_writable: Optional[bool]) -> None:
939931
"""Updates the is_writable attribute on all sockets currently in the
940932
Pool.
@@ -1001,7 +993,7 @@ async def remove_stale_sockets(self, reference_generation: int) -> None:
1001993
async with self._max_connecting_cond:
1002994
# If maxConnecting connections are already being created
1003995
# by this pool then try again later instead of waiting.
1004-
if self._pending >= self.max_connecting:
996+
if self._pending >= self.opts.max_connecting:
1005997
return
1006998
self._pending += 1
1007999
incremented = True
@@ -1034,24 +1026,11 @@ def _handle_connection_error(self, error: BaseException, phase: str, conn_id: in
10341026
# Look for an AutoReconnect error raised from a ConnectionResetError with
10351027
# errno == errno.ECONNRESET or raised from an OSError that we've created due to
10361028
# a closed connection.
1037-
# If found, set backoff and add error labels.
1029+
# If found, add error labels.
10381030
if self.is_sdam or type(error) != AutoReconnect:
10391031
return
1040-
self._backoff += 1
10411032
error._add_error_label("SystemOverloadedError")
10421033
error._add_error_label("RetryableError")
1043-
# Log the pool backoff message.
1044-
if self.enabled_for_logging and _CONNECTION_LOGGER.isEnabledFor(logging.DEBUG):
1045-
_debug_log(
1046-
_CONNECTION_LOGGER,
1047-
message=_ConnectionStatusMessage.POOL_BACKOFF,
1048-
clientId=self._client_id,
1049-
serverHost=self.address[0],
1050-
serverPort=self.address[1],
1051-
driverConnectionId=conn_id,
1052-
reason=_verbose_connection_error_reason(ConnectionClosedReason.POOL_BACKOFF),
1053-
error=ConnectionClosedReason.POOL_BACKOFF,
1054-
)
10551034

10561035
async def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> AsyncConnection:
10571036
"""Connect to Mongo and return a new AsyncConnection.
@@ -1082,10 +1061,6 @@ async def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> A
10821061
driverConnectionId=conn_id,
10831062
)
10841063

1085-
# Apply backoff if applicable.
1086-
if self._backoff:
1087-
await asyncio.sleep(_backoff(self._backoff))
1088-
10891064
# Pass a context to determine if we successfully create a configured socket.
10901065
context = dict(has_created_socket=False)
10911066

@@ -1126,9 +1101,11 @@ async def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> A
11261101
self.active_contexts.discard(tmp_context)
11271102
if tmp_context.cancelled:
11281103
conn.cancel_context.cancel()
1104+
completed_hello = False
11291105
try:
11301106
if not self.is_sdam:
11311107
await conn.hello()
1108+
completed_hello = True
11321109
self.is_writable = conn.is_writable
11331110
if handler:
11341111
handler.contribute_socket(conn, completed_handshake=False)
@@ -1138,15 +1115,14 @@ async def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> A
11381115
except BaseException as e:
11391116
async with self.lock:
11401117
self.active_contexts.discard(conn.cancel_context)
1141-
self._handle_connection_error(e, "hello", conn_id)
1118+
if not completed_hello:
1119+
self._handle_connection_error(e, "hello", conn_id)
11421120
await conn.close_conn(ConnectionClosedReason.ERROR)
11431121
raise
11441122

11451123
if handler:
11461124
await handler.client._topology.receive_cluster_time(conn._cluster_time)
11471125

1148-
# Clear the backoff state.
1149-
self._backoff = 0
11501126
return conn
11511127

11521128
@contextlib.asynccontextmanager
@@ -1323,7 +1299,7 @@ async def _get_conn(
13231299
# to be checked back into the pool.
13241300
async with self._max_connecting_cond:
13251301
self._raise_if_not_ready(checkout_started_time, emit_event=False)
1326-
while not (self.conns or self._pending < self.max_connecting):
1302+
while not (self.conns or self._pending < self.opts.max_connecting):
13271303
timeout = deadline - time.monotonic() if deadline else None
13281304
if not await _async_cond_wait(self._max_connecting_cond, timeout):
13291305
# Timed out, notify the next thread to ensure a
@@ -1469,7 +1445,7 @@ async def _perished(self, conn: AsyncConnection) -> bool:
14691445
:class:`~pymongo.errors.AutoReconnect` exceptions on server
14701446
hiccups, etc. We only check if the socket was closed by an external
14711447
error if it has been > 1 second since the socket was checked into the
1472-
pool, or we are in backoff mode, to keep performance reasonable -
1448+
pool to keep performance reasonable -
14731449
we can't avoid AutoReconnects completely anyway.
14741450
"""
14751451
idle_time_seconds = conn.idle_time_seconds()
@@ -1482,8 +1458,6 @@ async def _perished(self, conn: AsyncConnection) -> bool:
14821458
return True
14831459

14841460
check_interval_seconds = self._check_interval_seconds
1485-
if self._backoff:
1486-
check_interval_seconds = 0
14871461
if check_interval_seconds is not None and (
14881462
check_interval_seconds == 0 or idle_time_seconds > check_interval_seconds
14891463
):

pymongo/synchronous/pool.py

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
from pymongo.server_type import SERVER_TYPE
8585
from pymongo.socket_checker import SocketChecker
8686
from pymongo.synchronous.client_session import _validate_session_write_concern
87-
from pymongo.synchronous.helpers import _backoff, _handle_reauth
87+
from pymongo.synchronous.helpers import _handle_reauth
8888
from pymongo.synchronous.network import command
8989

9090
if TYPE_CHECKING:
@@ -788,7 +788,6 @@ def __init__(
788788
self._max_connecting_cond = _create_condition(self.lock)
789789
self._pending = 0
790790
self._client_id = client_id
791-
self._backoff = 0
792791
if self.enabled_for_cmap:
793792
assert self.opts._event_listeners is not None
794793
self.opts._event_listeners.publish_pool_created(
@@ -844,8 +843,6 @@ def _reset(
844843
with self.size_cond:
845844
if self.closed:
846845
return
847-
# Clear the backoff state.
848-
self._backoff = 0
849846
if self.opts.pause_enabled and pause and not self.opts.load_balanced:
850847
old_state, self.state = self.state, PoolState.PAUSED
851848
self.gen.inc(service_id)
@@ -928,11 +925,6 @@ def _reset(
928925
for conn in sockets:
929926
conn.close_conn(ConnectionClosedReason.STALE)
930927

931-
@property
932-
def max_connecting(self) -> int:
933-
"""The current max connecting limit for the pool."""
934-
return 1 if self._backoff else self.opts.max_connecting
935-
936928
def update_is_writable(self, is_writable: Optional[bool]) -> None:
937929
"""Updates the is_writable attribute on all sockets currently in the
938930
Pool.
@@ -997,7 +989,7 @@ def remove_stale_sockets(self, reference_generation: int) -> None:
997989
with self._max_connecting_cond:
998990
# If maxConnecting connections are already being created
999991
# by this pool then try again later instead of waiting.
1000-
if self._pending >= self.max_connecting:
992+
if self._pending >= self.opts.max_connecting:
1001993
return
1002994
self._pending += 1
1003995
incremented = True
@@ -1030,24 +1022,11 @@ def _handle_connection_error(self, error: BaseException, phase: str, conn_id: in
10301022
# Look for an AutoReconnect error raised from a ConnectionResetError with
10311023
# errno == errno.ECONNRESET or raised from an OSError that we've created due to
10321024
# a closed connection.
1033-
# If found, set backoff and add error labels.
1025+
# If found, add error labels.
10341026
if self.is_sdam or type(error) != AutoReconnect:
10351027
return
1036-
self._backoff += 1
10371028
error._add_error_label("SystemOverloadedError")
10381029
error._add_error_label("RetryableError")
1039-
# Log the pool backoff message.
1040-
if self.enabled_for_logging and _CONNECTION_LOGGER.isEnabledFor(logging.DEBUG):
1041-
_debug_log(
1042-
_CONNECTION_LOGGER,
1043-
message=_ConnectionStatusMessage.POOL_BACKOFF,
1044-
clientId=self._client_id,
1045-
serverHost=self.address[0],
1046-
serverPort=self.address[1],
1047-
driverConnectionId=conn_id,
1048-
reason=_verbose_connection_error_reason(ConnectionClosedReason.POOL_BACKOFF),
1049-
error=ConnectionClosedReason.POOL_BACKOFF,
1050-
)
10511030

10521031
def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> Connection:
10531032
"""Connect to Mongo and return a new Connection.
@@ -1078,10 +1057,6 @@ def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> Connect
10781057
driverConnectionId=conn_id,
10791058
)
10801059

1081-
# Apply backoff if applicable.
1082-
if self._backoff:
1083-
time.sleep(_backoff(self._backoff))
1084-
10851060
# Pass a context to determine if we successfully create a configured socket.
10861061
context = dict(has_created_socket=False)
10871062

@@ -1122,9 +1097,11 @@ def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> Connect
11221097
self.active_contexts.discard(tmp_context)
11231098
if tmp_context.cancelled:
11241099
conn.cancel_context.cancel()
1100+
completed_hello = False
11251101
try:
11261102
if not self.is_sdam:
11271103
conn.hello()
1104+
completed_hello = True
11281105
self.is_writable = conn.is_writable
11291106
if handler:
11301107
handler.contribute_socket(conn, completed_handshake=False)
@@ -1134,15 +1111,14 @@ def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> Connect
11341111
except BaseException as e:
11351112
with self.lock:
11361113
self.active_contexts.discard(conn.cancel_context)
1137-
self._handle_connection_error(e, "hello", conn_id)
1114+
if not completed_hello:
1115+
self._handle_connection_error(e, "hello", conn_id)
11381116
conn.close_conn(ConnectionClosedReason.ERROR)
11391117
raise
11401118

11411119
if handler:
11421120
handler.client._topology.receive_cluster_time(conn._cluster_time)
11431121

1144-
# Clear the backoff state.
1145-
self._backoff = 0
11461122
return conn
11471123

11481124
@contextlib.contextmanager
@@ -1319,7 +1295,7 @@ def _get_conn(
13191295
# to be checked back into the pool.
13201296
with self._max_connecting_cond:
13211297
self._raise_if_not_ready(checkout_started_time, emit_event=False)
1322-
while not (self.conns or self._pending < self.max_connecting):
1298+
while not (self.conns or self._pending < self.opts.max_connecting):
13231299
timeout = deadline - time.monotonic() if deadline else None
13241300
if not _cond_wait(self._max_connecting_cond, timeout):
13251301
# Timed out, notify the next thread to ensure a
@@ -1465,7 +1441,7 @@ def _perished(self, conn: Connection) -> bool:
14651441
:class:`~pymongo.errors.AutoReconnect` exceptions on server
14661442
hiccups, etc. We only check if the socket was closed by an external
14671443
error if it has been > 1 second since the socket was checked into the
1468-
pool, or we are in backoff mode, to keep performance reasonable -
1444+
pool to keep performance reasonable -
14691445
we can't avoid AutoReconnects completely anyway.
14701446
"""
14711447
idle_time_seconds = conn.idle_time_seconds()
@@ -1478,8 +1454,6 @@ def _perished(self, conn: Connection) -> bool:
14781454
return True
14791455

14801456
check_interval_seconds = self._check_interval_seconds
1481-
if self._backoff:
1482-
check_interval_seconds = 0
14831457
if check_interval_seconds is not None and (
14841458
check_interval_seconds == 0 or idle_time_seconds > check_interval_seconds
14851459
):

0 commit comments

Comments
 (0)