我正在使用client.map在N个单线程工作器(在N台计算机上)的池上运行一个函数,其中一个工作器失败。我想知道是否有一种方法可以自动处理工作程序引发的异常,将失败的任务重新分配给其他工作程序,并从池中忽略或排除它?
我尝试使用下面显示的方法来模拟问题。为了使一个工作人员失败,我在my_function
中引发了一个OSError,它像这样client.map
提交给futures = client.map(my_function, range(100))
。在我的示例中,“ Computer123”上的工作程序将失败。为了处理my_function
引发的异常,我在exception_handler
中使用sys.exit。因此,当任务在工作线程上失败时,将调用sys.exit。结果是,当客户端重新分发其失败的任务时,不良工作程序的distributed.nanny会捕获故障并重新启动工作程序。但是一旦坏员工再次备份,由于它仍在池中,它将再次接收任务。它再次失败,然后重复该过程。随着故障的继续,最终其他工人将完成所有任务。如果我能够自动处理来自“ Computer123”之类的不良工人的异常并将其从池中删除,那将是理想的选择。也许我只需要将它从游泳池中删除?
@exception_handler
def my_function(x):
import socket
import time
time.sleep(5)
if socket.gethostname() == 'Computer123':
raise(OSError)
else:
return x**2
def exception_handler(orig_func):
def wrapper(*args,**kwargs):
try:
return orig_func(*args,**kwargs)
except:
import sys
sys.exit(1)
return wrapper
答案 0 :(得分:0)
作为一种解决方法,您可以保留一个坏工人字典,在每次您确定它不好时(可能在它引发一定数量的异常之后),都将主机名添加到该字典中。
然后,当您要发出某些任务时,请检查它是否在有问题的列表中。像这样:
if socket.gethostname() in badHosts:
skip
else:
do_something()
如果您可以提供有关如何管理连接到的池的更多详细信息,我也许可以提供一些有关如何直接删除它们的更多建议,而不必每次都进行检查。