2

似乎 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;
4

2 回答 2

2

您仍然没有添加任何有关问题所在的信息。但我看到了其他一些我想评论的东西。

当前工作目录

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

您希望通过 cwd 执行 rail 的愿望Path最好通过以下方式实现:

_ ->
    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​​ on rails 每个进程需要大量内存,所以这可能是一个明智的决定)。

如果您不需要像示例代码中那样使用昂贵调用中的任何值更新 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).
于 2009-09-05T15:44:08.593 回答
2

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

Does the return contain everything you expect it to?

于 2009-09-06T01:52:37.263 回答