2

Erlang プロセスは、たとえ作業が終了しても 5 秒のデフォルト タイムアウトまで生き続けるようです。

ウィンドウ CLI にコマンドを発行する gen_server 呼び出しがあります。コマンドは 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;
4

2 に答える 2

2

os:cmd が結果を返すのに時間がかかっていると思います。おそらく、os:cmd が rails コマンドがいつ完了したかを伝えるのに問題があり、プロセスがタイムアウトをトリガーするまで返されない可能性があります。しかし、あなたのコードから、最も可能性の高い原因は os:cmd 呼び出しだと思います。

返品には、期待するすべてが含まれていますか?

于 2009-09-06T01:52:37.263 に答える
2

問題が何であるかについての情報をまだ追加していません。しかし、他にもコメントしたいことがいくつかあります。

現在の作業ディレクトリ

使用してfile:set_cwd(Path)いるため、開始されたコマンドはそのパスを継承します。ファイル サーバーの cwd はグローバルです。おそらく、アプリケーション コードではまったく使用しないでください。erlang のクラッシュ ダンプを書きたい場所などに cwd を設定するのに便利です。

レールを cwd で実行させたいというあなたの願いは、次のPathようなものでうまく機能します:

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

つまり、シェルを起動してコマンド ラインを解析し、シェルで cwd を変更して Rails を起動します。

gen_server のブロック

gen_server は、処理をシリアル化するために存在します。つまり、メッセージを次々と処理します。それらすべてを同時に処理するわけではありません。それらを同時に処理しないことが存在理由です。

(他のコストに関連して) gen_server で非常にコストのかかる計算を行っています: この Rails アプリケーションを実行する外部プロセスを開始します。一度に最大 1 つの 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 に答える