新的Erlang和只是有点麻烦让我的头围绕新的范式!erlang主管最好的方式来处理ibrowse:send_req conn_failed
OK,所以我有一个OTP gen_server在这个内部函数:
my_func() ->
Result = ibrowse:send_req(?ROOTPAGE,[{"User-Agent",?USERAGENT}],get),
case Result of
{ok, "200", _, Xml} -> %<<do some stuff that won't interest you>>
,ok;
{error,{conn_failed,{error,nxdomain}}} -> <<what the heck do I do here?>>
end.
如果我离开了的情况下处理,然后失败,我得到传播到主管的退出信号的连接,它被关闭与服务器一起。
我想要发生的事情(至少我认为这是我想要发生的事情)是,在连接失败时,我想暂停,然后重试send_req说10次,那时管理员可能会失败。
如果我做了什么丑像这样...
{error,{conn_failed,{error,nxdomain}}} -> stop()
它关闭服务器进程,是的,我明白,直到它不能用我的(尝试在10秒内10次)重启战略,也是期望的结果,但是当我真的想返回{error,error_but_please_dont_fall_over_mr_supervisor}时,从服务器到管理员的返回值是'ok'。
我强烈怀疑在这种情况下,我应该处理所有的业务内容,比如在'my_func'中重试失败的连接,而不是试图让流程停止,然后让管理员重新启动它以便尝试再次。
问题:在这种情况下,“Erlang方式”是什么?
是的,我尝试了一些类似的东西(比你的解决方案略差一些),传递尝试的次数然后递减并测试为零。唯一的区别是我调用stop()而不是返回一个元组,停止会关闭服务器(并重新启动它),但不会返回有用的消息,{error,too_many_retries}将返回一条有用的消息,但不会关闭服务器。 – unclejimbob
我希望找到一个解决方案来获得这两个世界的组合,因为send_req错误出现我重试了10次,然后如果它仍然失败,我抓住它,然后再次抛出,但以避免导致监督员失败 - 但我也认为这不是'Erlang的方式'。我认为你的解决方案是要走的路,因为如果发生任何其他异常,它应该由主管的重启战略覆盖。 如果其他人有不同的方法或意见,那么一定要通过。 非常感谢 – unclejimbob
@unclejimbob从我所了解的情况来看,只有在达到最大尝试次数时,才想让监督人员失败,对吗?然后让监督员重新启动工作人员,以便从顶部重试整个操作。这是我试图用代码做的事情。你可能想用erlang来补充它:error(too_many_attempts)。所以,只有在达到最大尝试或抛出未知错误(未捕获)时,才会“让它崩溃”。我不喜欢定时器:sleep()是你的工作人员不服从sys消息,所以另一种解决方案是接收超时 – marcelog