Django-每x秒运行一个函数

发布于 2021-01-29 15:09:24

我正在开发Django应用。我有一个API端点,如果需要,它必须执行必须重复几次的功能(直到满足特定条件为止)。我现在如何处理-

def shut_down(request):
  # Do some stuff
  while True:
    result = some_fn()
    if result:
      break
    time.sleep(2)

  return True

虽然我知道这是一种可怕的方法,并且我不应该阻塞2秒钟,但是我不知道该如何解决。
等待4秒后,此方法起作用。但是我想要使循环在后台运行并在some_fn返回True时停止的东西。(此外,可以肯定some_fn将返回True)

编辑-
阅读Oz123的响应给了我一个似乎可行的想法。这是我所做的-

def shut_down(params):
    # Do some stuff
    # Offload the blocking job to a new thread

    t = threading.Thread(target=some_fn, args=(id, ), kwargs={})
    t.setDaemon(True)
    t.start()

    return True

def some_fn(id):
    while True:
        # Do the job, get result in res
        # If the job is done, return. Or sleep the thread for 2 seconds before trying again.

        if res:
            return
        else:
            time.sleep(2)

这为我完成了工作。很简单,但我不知道与Django结合使用多线程的效率如何。
如果有人能指出这一点的缺陷,请多多指教。

关注者
0
被浏览
125
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    对于许多小型项目来说,芹菜实在是太过分了。对于那些项目,您可以使用schedule,它非常易于使用。

    使用此库,您可以使任何函数定期执行任务:

    import schedule
    import time
    
    def job():
        print("I'm working...")
    
    schedule.every(10).minutes.do(job)
    schedule.every().hour.do(job)
    schedule.every().day.at("10:30").do(job)
    schedule.every().monday.do(job)
    schedule.every().wednesday.at("13:15").do(job)
    
    while True:
        schedule.run_pending()
        time.sleep(1)
    

    该示例以阻塞方式运行,但是如果您查看FAQ,您会发现您还可以在并行线程中运行任务,以使您不会阻塞,并且一旦不再需要就删除该任务:

    from schedule import Scheduler
    
    def run_continuously(self, interval=1):
        """Continuously run, while executing pending jobs at each elapsed
        time interval.
        @return cease_continuous_run: threading.Event which can be set to
        cease continuous run.
        Please note that it is *intended behavior that run_continuously()
        does not run missed jobs*. For example, if you've registered a job
        that should run every minute and you set a continuous run interval
        of one hour then your job won't be run 60 times at each interval but
        only once.
        """
    
        cease_continuous_run = threading.Event()
    
        class ScheduleThread(threading.Thread):
    
            @classmethod
            def run(cls):
                while not cease_continuous_run.is_set():
                    self.run_pending()
                    time.sleep(interval)
    
        continuous_thread = ScheduleThread()
        continuous_thread.setDaemon(True)
        continuous_thread.start()
        return cease_continuous_run
    
    
    Scheduler.run_continuously = run_continuously
    

    这是在类方法中使用的示例:

        def foo(self):
            ...
            if some_condition():
               return schedule.CancelJob  # a job can dequeue it
    
        # can be put in __enter__ or __init__
        self._job_stop = self.scheduler.run_continuously()
    
        logger.debug("doing foo"...)
        self.foo() # call foo
        self.scheduler.every(5).seconds.do(
            self.foo) # schedule foo for running every 5 seconds
    
        ...
        # later on foo is not needed any more:
        self._job_stop.set()
    
        ...
    
        def __exit__(self, exec_type, exc_value, traceback):
            # if the jobs are not stop, you can stop them
            self._job_stop.set()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看