【问题标题】:Make a process end before timeout在超时前结束进程
【发布时间】:2010-11-25 19:08:03
【问题描述】:

似乎 erlang 进程会一直保持活动状态,直到 5 秒默认超时,即使它已经完成了它的工作。

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

EDIT此调用在 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;

【问题讨论】:

  • 你能发布一些示例代码来演示这个问题吗?
  • 确保 sasl 已启动 ( application:start(sasl) ) 以便获得良好的错误报告。

标签: erlang erlang-otp


【解决方案1】:

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

退货是否包含您期望的所有内容?

【讨论】:

  • 是的,返回正是我所期望的(创建的文件列表),我同意它必须是 os:cmd 调用,因为 vanilla 进程几乎立即返回。我想你已经回答了我的问题,而且我很愚蠢。我想这就是熬夜到凌晨 3 点,学习一门新语言对你的影响。但是你从你的错误中学习,我从你的回答中学到了很多东西,谢谢
  • 没问题。我犯了一些愚蠢的错误,相信我。正如你所说,这是我们学习的一部分。
【解决方案2】:

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

当前工作目录

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

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

_ ->
    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).

【讨论】:

  • 感谢您的回答,它对我学习 erlang 的过程有很大帮​​助。但是,我尝试了使用 gen_server:reply/2 的建议,但它似乎没有给我任何不同。我不明白目的。我很高兴这个动作是同步的(我想在我做任何其他事情之前等待它完成)但它似乎需要比实际的 Rails 动作更长的时间来返回。
  • 在我看来,Rails 操作正在执行,比如说在 2 秒内,但直到 5 秒后 gen_server 超时我才看到结果。我认为默认超时是 5 秒是正确的吗?对不起,如果我在这里很愚蠢,但我 3 天前才开始学习 erlang,感谢我能得到的所有帮助。
  • 我不确定你没有更快地看到结果是 erlangs 的错。超时不应导致 erlang 进程需要更长的时间才能返回。我猜你的 rails 命令需要更长的时间,或者 rails 命令的结果需要更长的时间才能被 erlang 返回。你有没有尝试过运行一个原版的进程,它只是返回而不做任何事情?我敢打赌,那时你不会放缓。
  • 该死!你是对的,这是 Rails 的错,5 秒的事情让我很困惑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 2022-10-04
  • 1970-01-01
  • 2019-12-08
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
相关资源
最近更新 更多