再会,

我有一个gen_server进程,它会定期执行一些长时间运行的状态更新任务handle_info:

handle_info(trigger, State) ->
    NewState = some_long_running_task(),
    erlang:send_after(?LOOP_TIME, self(), trigger),
    {noreply, NewState}.

但是,当此类任务运行时,整个服务器将变得无响应,对其的任何调用都将导致整个服务器崩溃:
my_gen_server:status().
** exception exit: {timeout,{gen_server,call,[my_gen_server,status]}}
     in function  gen_server:call/2

如何避免gen_server的阻塞?
当任何时候调用my_gen_server:status()时,结果应该是这样的:{ok, task_active}

最佳答案

在一个单独的过程中执行长期运行的任务。让该进程将其在任务中的进度通知gen_server(也就是说,是否可以跟踪任务的进度),或者让该进程完成任务或失败,但至少将任务的结果告知gen_server。

让gen_server与执行此长时间运行任务的进程链接,并让gen_server知道PID或注册名称,以便在退出信号出现的情况下,可以将重要进程的死亡与其余进程隔离开来。

handle_info(触发状态)->
Pid = spawn_link(?MODULE,some_long_running_task,[State]),
NewState = save_pid(Pid,State),
{noreply,NewState};
handle_info({'EXIT',SomePid,_},State)->
case lookup_pid(State)==的某些
假-> %%其他过程
{noreply,State};
正确->
%%我们的流程已终止
%% 我们现在干什么 ?
%%产生了另一个?
%%多数民众赞成在您做出决定后
....
....
{noreply,State}
结尾;
handle_info({finished,TaskResult},State)->
..... %%更新状态等
erlang:send_after(?LOOP_TIME,self(),trigger),
{noreply,NewState}。

some_long_running_task(ServerState)->
....做工作
....返回结果

关于Erlang gen_server具有长时间运行的任务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8879177/

10-17 01:25