Django-每x秒运行一个函数
我正在开发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结合使用多线程的效率如何。
如果有人能指出这一点的缺陷,请多多指教。
-
对于许多小型项目来说,芹菜实在是太过分了。对于那些项目,您可以使用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()