My Django Application contains celery based tasks, which download certain files from a SFTP server every time it executes. Till now i create an SFTP connection every time a job starts and close the connection at the end of job. But some how it is cause file descriptor error in code (too many SFTP connection opened). I am thinking of making SFTP connection via a singleton class so that only one SFTP connection gets established and that to only at the time when i start the gunicorn/celery services.
Is there a way i can execute the python code to create an SFTP connection only once when the application comes up or gets restarted? and its closed the services are stopped?
class Singleton:
def __init__(self, klass):
self.klass = klass
self.instance = None
def __call__(self, *args, **kwds):
if self.instance is None:
self.instance = self.klass(*args, **kwds)
return self.instance
@Singleton
class SFTP_SINGLETON(object):
def __init__(self, hostname=None, username=None, password=None, port=22, default_path=None):
self._hostname = hostname
self._username = username
self._Password = password
self._sftp = None
self._port = port
self._default_path = default_path
self._sftp_live = False
self._transport = self._start_transport()
def _start_transport(self):
try:
self._transport = paramiko.Transport((self._hostname, self._port))
self._transport.connect(username=self._username, password=self._Password)
logger.info(" connected to {} : {}".format(self._hostname, self._port))
return self._transport
except (AttributeError, socket.gaierror) as e:
# couldn't connect
logger.info(" exception in establish_connection : %s ", e)
raise ConnectionException(self._hostname, self._port)
def connect(self):
"""Establish the SFTP connection."""
if not self._sftp_live:
self._sftp = paramiko.SFTPClient.from_transport(self._transport)
# if self._default_path is not None:
# self._sftp.chdir(self._default_path)
self._sftp_live = True
def close(self):
"""Closes the connection and cleans up."""
# Close SFTP Connection.
if self._sftp_live:
self._sftp.close()
self._sftp_live = False
# Close the SSH Transport.
if self._transport:
self._transport.close()
self._transport = None