Skip to content

Commit 55f831e

Browse files
SNOW-1848371 adding connection.is_valid to perform connection validation on TCP/IP and Session levels (#2117)
Co-authored-by: Mark Keller <[email protected]>
1 parent 138241c commit 55f831e

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

DESCRIPTION.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
1313
- Adding support for the new PAT authentication method.
1414
- Updated README.md to include instructions on how to verify package signatures using `cosign`.
1515
- Updated the log level for cursor's chunk rowcount from INFO to DEBUG
16+
- Added a feature to verify if the connection is still good enough to send queries over.
1617

1718
- v3.12.4(December 3,2024)
1819
- Fixed a bug where multipart uploads to Azure would be missing their MD5 hashes.

src/snowflake/connector/connection.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,7 +1677,7 @@ def _log_telemetry(self, telemetry_data) -> None:
16771677
self._telemetry.try_add_log_to_batch(telemetry_data)
16781678

16791679
def _add_heartbeat(self) -> None:
1680-
"""Add an hourly heartbeat query in order to keep connection alive."""
1680+
"""Add a periodic heartbeat query in order to keep connection alive."""
16811681
if not self.heartbeat_thread:
16821682
self._validate_client_session_keep_alive_heartbeat_frequency()
16831683
heartbeat_wref = weakref.WeakMethod(self._heartbeat_tick)
@@ -1703,7 +1703,7 @@ def _cancel_heartbeat(self) -> None:
17031703
logger.debug("stopped heartbeat")
17041704

17051705
def _heartbeat_tick(self) -> None:
1706-
"""Execute a hearbeat if connection isn't closed yet."""
1706+
"""Execute a heartbeat if connection isn't closed yet."""
17071707
if not self.is_closed():
17081708
logger.debug("heartbeating!")
17091709
self.rest._heartbeat()
@@ -1990,3 +1990,21 @@ def _log_telemetry_imported_packages(self) -> None:
19901990
connection=self,
19911991
)
19921992
)
1993+
1994+
def is_valid(self) -> bool:
1995+
"""This function tries to answer the question: Is this connection still good for sending queries?
1996+
Attempts to validate the connections both on the TCP/IP and Session levels."""
1997+
logger.debug("validating connection and session")
1998+
if self.is_closed():
1999+
logger.debug("connection is already closed and not valid")
2000+
return False
2001+
2002+
try:
2003+
logger.debug("trying to heartbeat into the session to validate")
2004+
hb_result = self.rest._heartbeat()
2005+
session_valid = hb_result.get("success")
2006+
logger.debug("session still valid? %s", session_valid)
2007+
return bool(session_valid)
2008+
except Exception as e:
2009+
logger.debug("session could not be validated due to exception: %s", e)
2010+
return False

test/integ/test_connection.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,3 +1462,12 @@ def test_disable_telemetry(conn_cnx, caplog):
14621462
cur.execute("select 1").fetchall()
14631463
assert not conn.telemetry_enabled
14641464
assert "POST /telemetry/send" not in caplog.text
1465+
1466+
1467+
@pytest.mark.skipolddriver
1468+
def test_is_valid(conn_cnx):
1469+
"""Tests whether connection and session validation happens."""
1470+
with conn_cnx() as conn:
1471+
assert conn
1472+
assert conn.is_valid() is True
1473+
assert conn.is_valid() is False

0 commit comments

Comments
 (0)