Close dangling sockets

This commit is contained in:
zandercymatics 2023-11-15 14:59:17 -07:00
parent 652086a771
commit ffb7276a8a
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
3 changed files with 16 additions and 10 deletions

View file

@ -106,6 +106,7 @@ class EPPLibWrapper:
# Flag that the pool is frozen, # Flag that the pool is frozen,
# then restart the pool. # then restart the pool.
self.pool_status.pool_hanging = True self.pool_status.pool_hanging = True
logger.error("Pool timed out")
self.start_connection_pool() self.start_connection_pool()
except (ValueError, ParsingError) as err: except (ValueError, ParsingError) as err:
message = f"{cmd_type} failed to execute due to some syntax error." message = f"{cmd_type} failed to execute due to some syntax error."
@ -174,6 +175,7 @@ class EPPLibWrapper:
def _create_pool(self, client, login, options): def _create_pool(self, client, login, options):
"""Creates and returns new pool instance""" """Creates and returns new pool instance"""
logger.info("New pool was created")
return EPPConnectionPool(client, login, options) return EPPConnectionPool(client, login, options)
def start_connection_pool(self, restart_pool_if_exists=True): def start_connection_pool(self, restart_pool_if_exists=True):
@ -187,7 +189,7 @@ class EPPLibWrapper:
# Since we reuse the same creds for each pool, we can test on # Since we reuse the same creds for each pool, we can test on
# one socket, and if successful, then we know we can connect. # one socket, and if successful, then we know we can connect.
if not self._test_registry_connection_success(): if not self._test_registry_connection_success():
logger.warning("Cannot contact the Registry") logger.warning("start_connection_pool() -> Cannot contact the Registry")
self.pool_status.connection_success = False self.pool_status.connection_success = False
else: else:
self.pool_status.connection_success = True self.pool_status.connection_success = True
@ -197,6 +199,7 @@ class EPPLibWrapper:
if self._pool is not None and restart_pool_if_exists: if self._pool is not None and restart_pool_if_exists:
logger.info("Connection pool restarting...") logger.info("Connection pool restarting...")
self.kill_pool() self.kill_pool()
logger.info("Old pool killed")
self._pool = self._create_pool(self._client, self._login, self.pool_options) self._pool = self._create_pool(self._client, self._login, self.pool_options)
@ -221,6 +224,7 @@ class EPPLibWrapper:
credentials are valid, and/or if the Registrar credentials are valid, and/or if the Registrar
can be contacted can be contacted
""" """
# This is closed in test_connection_success
socket = Socket(self._client, self._login) socket = Socket(self._client, self._login)
can_login = False can_login = False

View file

@ -31,6 +31,7 @@ class Socket:
def connect(self): def connect(self):
"""Use epplib to connect.""" """Use epplib to connect."""
logger.info("Opening socket on connection pool")
self.client.connect() self.client.connect()
response = self.client.send(self.login) response = self.client.send(self.login)
if self.is_login_error(response.code): if self.is_login_error(response.code):
@ -40,11 +41,13 @@ class Socket:
def disconnect(self): def disconnect(self):
"""Close the connection.""" """Close the connection."""
logger.info("Closing socket on connection pool")
try: try:
self.client.send(commands.Logout()) self.client.send(commands.Logout())
self.client.close() self.client.close()
except Exception: except Exception as err:
logger.warning("Connection to registry was not cleanly closed.") logger.warning("Connection to registry was not cleanly closed.")
logger.error(err)
def send(self, command): def send(self, command):
"""Sends a command to the registry. """Sends a command to the registry.
@ -77,19 +80,14 @@ class Socket:
try: try:
self.client.connect() self.client.connect()
response = self.client.send(self.login) response = self.client.send(self.login)
except LoginError as err: except (LoginError, OSError) as err:
logger.error(err)
if err.should_retry() and counter < 10: if err.should_retry() and counter < 10:
counter += 1 counter += 1
sleep((counter * 50) / 1000) # sleep 50 ms to 150 ms sleep((counter * 50) / 1000) # sleep 50 ms to 150 ms
else: # don't try again else: # don't try again
return False return False
# Occurs when an invalid creds are passed in - such as on localhost
except OSError as err:
logger.error(err)
return False
else: else:
self.disconnect()
# If we encounter a login error, fail # If we encounter a login error, fail
if self.is_login_error(response.code): if self.is_login_error(response.code):
logger.warning("A login error was found in test_connection_success") logger.warning("A login error was found in test_connection_success")
@ -97,3 +95,5 @@ class Socket:
# Otherwise, just return true # Otherwise, just return true
return True return True
finally:
self.disconnect()

View file

@ -98,6 +98,7 @@ class EPPConnectionPool(ConnectionPool):
"""Kills all active connections in the pool.""" """Kills all active connections in the pool."""
try: try:
if len(self.conn) > 0 or len(self.greenlets) > 0: if len(self.conn) > 0 or len(self.greenlets) > 0:
logger.info("Attempting to kill connections")
gevent.killall(self.greenlets) gevent.killall(self.greenlets)
self.greenlets.clear() self.greenlets.clear()
@ -107,6 +108,7 @@ class EPPConnectionPool(ConnectionPool):
# Clear the semaphore # Clear the semaphore
self.lock = BoundedSemaphore(self.size) self.lock = BoundedSemaphore(self.size)
logger.info("Finished killing connections")
else: else:
logger.info("No connections to kill.") logger.info("No connections to kill.")
except Exception as err: except Exception as err: