【问题标题】:How do I make a decorator for Django management command processing locking?如何为 Django 管理命令处理锁定制作装饰器?
【发布时间】:2020-08-27 02:48:06
【问题描述】:

我有一个 Django 项目,其中包含许多从 crontab 执行的自定义管理命令。我需要在这些命令中实现锁定,以防止 cron 启动命令执行的多个实例。因此,我正在检查每个自定义管理命令并进行更改:

    def handle(self, *args, **options):
        ...

到:

from lockmgr.lockmgr import LockMgr, Locked

...

    def run_handle(self, *args, **options):
        ''' I renamed handle() to run_handle(). '''
        ...


    def handle(self, *args, **options):

        command = sys.argv[1]
        try:
            with LockMgr(f'{command}_lock') as l:
                self.run_handle(*args, **options)

        except Locked as e:
            errmsg = f'{command} failed to lock. Reason: {e}.'
            self.stdout.write(errmsg)
            self.logger.error(errmsg)

然后我开始想我应该在这里使用“装饰器”,但我不太确定该怎么做。任何帮助都会很棒。

谢谢。

【问题讨论】:

  • 我不确定您的用例是什么,但按顺序运行管理命令的最简单方法是只使用一个命令自上而下按顺序运行您的功能。这样你就不需要装饰器或任何类似的东西。也许如果可以分享您的用例,可以提出更好的方法。

标签: django python-3.x python-decorators


【解决方案1】:

啊,想通了。我需要创建一个python文件...

myproject/decorators/lock_cron_job.py

from lockmgr.lockmgr import LockMgr, Locked
import logging
import sys


def lock_cron_job():
    """Decorator that uses LockMgr."""
    def decorator(handle_func):
        def wrapped(*args, **kwargs):
            command = sys.argv[1]
            log = logging.getLogger(command)
            try:
                with LockMgr(f'{command}_lock'):
                    handle_func(*args, **kwargs)
            except Locked as e:
                errmsg = f'{command} failed to lock. Reason: {e}'
                log.error(errmsg)
        return wrapped
    return decorator

然后在我的自定义管理命令中我会这样做:

from myproject.decorators.lock_cron_job import lock_cron_job

...


    @lock_cron_job()
    def handle(self, *args, **options):
        ...

【讨论】:

    猜你喜欢
    • 2021-03-24
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 2021-11-14
    • 2012-12-28
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多