我有一个基本上充当Python脚本的浏览器界面的web2py应用程序。该脚本通常很快返回,但偶尔会花费很长时间。我想为用户提供一种停止脚本执行的方法,如果时间太长。通过多处理停止web2py中的长时间操作
我目前调用这样的功能:
def myView(): # this function is called from ajax
session.model = myFunc() # myFunc is from a module which i have complete control over
return dict(model=session.model)
myFunc
,当某些选项调用,使用多,但最终还是需要很长的时间。我需要一些方法来终止函数,或者至少是线程的子进程。
我想的第一件事是在一个新的进程中运行myFunc
,并推出自己的简单的事件系统来杀死它:
# in the controller
def myView():
p_conn, c_conn = multiprocessing.Pipe()
events = multiprocessing.Manager().dict()
proc = multiprocessing.Process(target=_fit, args=(options, events c_conn))
proc.start()
sleep(0.01)
session.events = events
proc.join()
session.model = p_conn.recv()
return dict(model=session.model)
def _fit(options, events pipe):
pipe.send(fitting.logistic_fit(options=options, events=events))
pipe.close()
def stop():
try:
session.events['kill']()
except SystemExit:
pass # because it raises that error intentionally
return dict()
# in the module
def kill():
print multiprocessing.active_children()
for p in multiprocessing.active_children():
p.terminate()
raise SystemExit
def myFunc(options, events):
events['kill'] = kill
我跑进与这几个主要问题。
- 在
stop()
会议并不总是一样的会议myView()
,所以session.events
没有。 - 即使会话相同,
kill()
也没有正确地杀死孩子。 - 长时间运行的函数会挂起web2py线程,所以
stop()
甚至在函数完成之前都没有处理。
我认为不叫join()
和使用AJAX在稍后的时间拿起函数的结果,但我没能保存过程对象session
供以后使用。管道似乎可以被酸洗,但是我遇到了无法从另一个视图访问同一个会话的问题。
我该如何实现此功能?
请问您可以扩展您的答案吗?一些值得回答的具体事情:调度程序是否立即从脚本启动任务?如何获得任务的结果?如何强制停止任务?事实上,这并不能完全回答这个问题。 – Scimonster
我已经更新了解决您最后一个问题的答案。您的前两个问题在链接文档中进行了介绍。由于它们涉及常规调度程序的功能并且不属于原始问题的一部分,因此我不会更新答案,但我会简要地提及,默认情况下,新任务会立即排队(并且您可以强制工作人员通过设置立即检查队列'immediate = True'),'scheduler.task_status()'方法用于检索结果。 – Anthony