Make process terminate before timeout

The erlang process seems to stay alive for up to 5 seconds by default, even though it exited.

I have a call to gen_server that issues a command to the CLI of a window, which can be completed in less than 1 second, but the process waits 5 seconds before I see the result of the operation. What's happening? it has to do with a timeout, or it could be something else.

EDIT This call does nothing for 5 seconds (default timeout!)

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


source to share


2 answers


I'm guessing os: cmd takes so long to return results. It might be possible that os: cmd doesn't know when the rails command will exit and won't return until the process timed out. But from your code, I would say that the most likely culprit is the os: cmd call.



Is the return what you expect?

+2


source


You still haven't added any information about what the problem is. But I see some other things that I would like to comment on.

Current working directory

You use file:set_cwd(Path)

to make the initial command inherit this path. The file server cdd is global. You probably shouldn't be using it at all in your application code. This is useful for setting cwd where you want erlang crash dumps, etc.

Your desire to allow rail execution with cwd is Path

better served with something like this:

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

      

That is, start a shell to parse the command line, type cwd shell and start Rails.

Gen_server lock



The gen_server general must do serialization. That is, it processes one message after another. It doesn't process them all at the same time. This is its reason for being not to process them at the same time.

You are (in relation to other costs) doing a very expensive computation in gen_server: starting an external process that runs this rails application. Do you ever intend to use at most one rails application? (I have heard about ruby ​​on rails requiring tons of memory per process, so this might be a smart solution).

If you don't need to update the state with any values ​​from an expensive call like in your example code, you can use an explicit call to gen_server: reply / 2.

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

      

And then you have

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

      

+2


source







All Articles