在超时之前使进程结束

时间:2009-09-04 23:09:50

标签: erlang otp

似乎erlang进程将保持活跃状态​​,直到5秒默认超时,即使它已完成它的工作。

我有一个gen_server调用,它向窗口CLI发出一个命令,该命令可以在不到1秒的时间内完成,但是在看到操作结果之前,该过程等待5秒。这是怎么回事?是否与超时有关,或者可能是其他事情。

编辑此调用在5秒内没有执行任何操作(默认超时!)

handle_call({create_app, Path, Name, Args}, _From, State) ->
case filelib:ensure_dir(Path) of
    {error, Reason} ->
        {reply, Reason, State};
    _ ->
        file:set_cwd(Path),
        Response = os:cmd(string:join(["Rails", Name, Args], " ")),
        {reply, Response, State}
end;

2 个答案:

答案 0 :(得分:2)

您仍然没有添加任何有关问题的信息。但我看到其他一些我想评论的事情。

当前工作目录

您正在使用file:set_cwd(Path),因此已启动的命令将继承该路径。文件服务器的cwd是全局的。您可能根本不应该在应用程序代码中使用它。将cwd设置为要写入erlang崩溃转储的位置等非常有用。

根据Path,您希望使用cwd执行铁路的愿望更适合这样的事情:

_ ->
    Response = os:cmd(string:join(["cd", Path, "&&", "Rails", Name, Args], " ")),
    {reply, Response, State}

也就是说,启动一个shell来解析命令行,让shell更改cwd和启动Rails。

阻止gen_server

gen_server用于序列化处理。也就是说,它一个接一个地处理一个消息。它不会同时处理它们。它存在的原因是不能同时处理它们。

您(与其他成本相关)在gen_server中执行一些非常昂贵的计算:启动运行此rails应用程序的外部进程。您是否打算在任何时候最多运行一个rails应用程序? (我听说过轨道上的ruby需要每个进程大量的内存,所以这可能是一个明智的决定。)

如果您不需要使用昂贵的调用中的任何值更新State,就像在示例代码中一样,那么您可以使用显式的gen_server:reply / 2调用。

_ ->
    spawn_link(fun () -> rails_cmd(From, Path, Name, Args) end),
    {no_reply, State}

然后你有

rails_cmd(From, Path, Name, Args) ->
    Response = os:cmd(string:join(["cd", Path, "&&", "Rails", Name, Args], " ")),
    gen_server:reply(From, Response).

答案 1 :(得分:2)

我猜测os:cmd需要很长时间才能返回结果。可能os:cmd可能无法确定rails命令何时完成,并且在进程触发超时之前不会返回。但是从你的代码中我会说最可能的罪魁祸首是os:cmd call。

回报是否包含您期望的所有内容?