tags:

views:

160

answers:

2

It seems that an erlang process will stay alive until the 5 sec default timeout even if it has finished it's work.

I have gen_server call that issues a command to the window CLI which can be completed in less than 1 sec but the process waits 5 sec before I see the result of the operation. What's going on? is it soemthing to do with the timeout, or might it be something else.

EDIT This call doesn't do anything for 5 seconds (the 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  A: 

You still have not added any information on what the problem is. But I see some other things I'd like to comment on.

Current working dir

You are using file:set_cwd(Path) so the started command will inherit that path. The cwd of the file server is global. You should probably not be using it at all in application code. It's useful for setting the cwd to where you want erlang crash dumps to be written etc.

Your desire to let rail execute with the cwd according to Path is 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, have the shell change cwd and the start Rails.

Blocking a gen_server

The gen_server is there to serialize processing. That is, it processes one message after the other. It doesn't handle them all concurrently. It is its reason for existence to not handle them concurrently.

You are (in relation to other costs) doing some very costly computation in the gen_server: starting an external process that runs this rails application. Is it your intention to have at most one rails application running at any one time? (I've heard about ruby on rails requiring tons of memory per process, so it might be a sensible decision).

If you dont need to update the State with any values from a costly call, as in your example code, then you can use an explicit gen_server:reply/2 call.

_ ->
    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).
Christian
Thanks for your answer, it has helped alot in my learning erlang process. However, i tried you suggestion of using gen_server:reply/2 and it didn't seem to give me anything different. I don't understand the purpose. I am quite happy for this action to be synchronous (I want to wait for it to complete before I do anything else) but it seems to be taking longer to return than the actual Rails action takes.
Damian
It seem s to me that the Rails action is being performed, say within 2 seconds but i do not see the results until the gen_server timesout after 5 seconds. Am I correct in beleiving that the default timeout is 5 seconds? Sorry if I am being stupid here, but I only started learning erlang 3 days ago, and appreciate all the help I can get.
Damian
I'm not sure it's erlangs fault that you don't see the result faster. Timeouts should not cause an erlang process to take longer to return. I would guess your rails command is taking longer or the result of the rails command is taking longer to to get returned by erlang. Have you tried running a vanilla process that just returns without doing anything? I'm betting your won't have the slowdown then.
Jeremy Wall
Damn! your are right, it's Rails' fault, the 5 second thing was confusing me
Damian
+1  A: 

I'm guessing the os:cmd is taking that long to return the results. It's possible that maybe the os:cmd is having trouble telling when the rails command is completed and doesn't return till the process triggers the timeout. But from your code I'd say the most likely culprit is the os:cmd call.

Does the return contain everything you expect it to?

Jeremy Wall
Yes the return is exactly what I expected (list of files created) and I agree it must be the os:cmd call due to the fact that the vanilla process returns almost instantaneously. I thnik you have answered my question and I was being pretty stupid. I guess thats what staying up till 3 in the morning, learning a new language does for you. But you learn though your mistakes, and Iam learning alot through your guys answers, Thanks
Damian
no problem. I've made my share of stupid mistakes believe me. Like you said that's part of how we learn.
Jeremy Wall