Erlang gen_server具有长时间运行的任务 [英] Erlang gen_server with long-running tasks

查看:134
本文介绍了Erlang gen_server具有长时间运行的任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

美好的一天,

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

I have a gen_server process which does some long-running state-updating tasks periodically in handle_info:

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

但是,当这样的任务运行时,整个服务器无响应,任何调用都会导致整个服务器崩溃:

But when such task runs, then whole server gets unresponsive and any call to it leads to whole server crash:

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}

How it is possible to avoid blocking of gen_server ? And when one call my_gen_server:status() at any time, the result should be something like: {ok, task_active}

推荐答案

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

execute the long running task in a separate process. Let this process inform the gen_server of its progress with the task (that is if the task's progress can be tracked) OR let the process complete the task or fail but at least inform the gen_server of the results of the task.

让gen_server与执行此长时间运行任务的进程链接,并让gen_server知道PID或注册名称,以便在退出信号的情况下,可以将该重要的死亡过程从休息。

Let the gen_server be linked with the process doing this long running task, and let the gen_server know the PID or registered name so that in case of exit signals, it can isolate the death of that important process from the Rest.

handle_info(trigger, State) ->
    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) == SomePid of
        false -> %% some other process
            {noreply,State};
        true ->
            %% our process has died
            %% what do we do now ?
            %% spawn another one ?
            %% thats your decision to take
            ....
            ....
            {noreply,State}
    end;
handle_info({finished,TaskResult},State)->
    .....%% update state e.t.c.
    erlang:send_after(?LOOP_TIME, self(), trigger),
    {noreply,NewState}.

some_long_running_task(ServerState)->
    ....do work
    ....return results

这篇关于Erlang gen_server具有长时间运行的任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆