當 gunicorn / celery 服務重新啟動時,Django 中有沒有辦法只執行一次 python 代碼? (Is there a way in Django to execute some python code only once when gunicorn / celery services are getting restarted?)


問題描述

當 gunicorn / celery 服務重新啟動時,Django 中有沒有辦法只執行一次 python 代碼? (Is there a way in Django to execute some python code only once when gunicorn / celery services are getting restarted?)

我的 Django 應用程序包含基於 celery 的任務,每次執行時都會從 SFTP 服務器下載某些文件。到現在為止,每次作業開始時我都會創建一個 SFTP 連接,並在作業結束時關閉連接。但是它是如何導致代碼中的文件描述符錯誤的(打開了太多的 SFTP 連接)。我正在考慮通過單例類建立 SFTP 連接,以便只建立一個 SFTP 連接,並且僅在我啟動 gunicorn/celery 服務時建立。

有沒有辦法我可以執行python代碼僅在應用程序啟動或重新啟動時一次創建SFTP連接?並且它關閉了服務停止了嗎?


參考解法

方法 1:

You can use global variables. Create a module sftp.py


sftp_connection = None

def create_sftp_connection():
     ...
     ...
     return sftp_connection

def get_sftp_connection():
     global sftp_connection
     if not sftp_connection:
         sftp_connection = create_sftp_connection()
     return sftp_connection

Then in all the usages, import get_sftp_connection and use

  sftp_connection = get_sftp_connection()
  ...

方法 2:

Singleton class

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

(by Rohit RanjanvestrongeLalit Suthar)

參考文件

  1. Is there a way in Django to execute some python code only once when gunicorn / celery services are getting restarted? (CC BY‑SA 2.5/3.0/4.0)

#gunicorn #Python #service #celery #sftp






相關問題

Heroku 無法啟動我的應用程序,但 `foreman start` 工作 (Heroku fails to start my app, but `foreman start` works)

為什麼不再推薦 gunicorn_django ? (Why is gunicorn_django not recommended anymore?)

Supervisord 拋出錯誤:“無法執行 /var/application/gunicorn_start:ENOEXEC” (Supervisord throws error: "couldn't exec /var/application/gunicorn_start: ENOEXEC")

服務器上更改的 HTML 文件未反映 (The HTML file changed on server is not reflected)

在 gae flexible 上長時間運行的雲任務會提前終止而不會出錯。如何調試?我錯過了什麼? (Long running cloud task on gae flexible terminates early without error. How to debug? What am I missing?)

Gunicorn 沒有自動啟動 (Gunicorn not starting automatically)

nginx的配置文件中的主機名未知? (Hostname in configfile of nginx unkown?)

重新啟動 gunicorn 和 nginx 不會反映拉取請求後的更改 (restarting gunicorn and nginx doesn't reflect changes after pull request)

當 gunicorn / celery 服務重新啟動時,Django 中有沒有辦法只執行一次 python 代碼? (Is there a way in Django to execute some python code only once when gunicorn / celery services are getting restarted?)

ModuleNotFoundError:在 Heroku 服務器上使用 Django 和 Gunicorn 時沒有名為“App Name”的模塊 (ModuleNotFoundError: No module named 'App Name' when using Django and Gunicorn on a heroku server)

kubernetes 正在暴露未聲明的端口 (kubernetes is exposing not declared port)

PM2.js 在 Virtualenv/Anaconda 環境中運行 Gunicorn/Flask 應用程序 (PM2.js to Run Gunicorn/Flask App inside Virtualenv/Anaconda env)







留言討論