Pergunta

Parece que um processo de Erlang permanecerá vivo até o tempo limite padrão de 5 segundos, mesmo que tenha terminado seu trabalho.

Eu tenho chamado Gen_Server que emite um comando para a CLI da janela que pode ser concluído em menos de 1 segundos, mas o processo aguarda 5 segundos antes de ver o resultado da operação. O que está acontecendo? É muito para ver com o tempo limite, ou pode ser outra coisa.

EDITAR Esta chamada não faz nada por 5 segundos (o tempo limite padrão!)

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;
Foi útil?

Solução

Suponho que o sistema operacional: CMD está demorando tanto para devolver os resultados. É possível que talvez o sistema operacional: CMD esteja tendo problemas para informar quando o comando Rails é concluído e não retornar até que o processo desencadeie o tempo limite. Mas, pelo seu código, eu diria que o culpado mais provável é o sistema operacional: CMD.

O retorno contém tudo o que você espera?

Outras dicas

Você ainda não adicionou nenhuma informação sobre qual é o problema. Mas vejo outras coisas que gostaria de comentar.

DIR de trabalho atual

Você está usando file:set_cwd(Path) Portanto, o comando iniciado herdará esse caminho. A CWD do servidor de arquivos é global. Você provavelmente não deve usá -lo no código do aplicativo. É útil para definir a CWD para onde você deseja que o Erlang Crash Dumps seja escrito etc.

Seu desejo de deixar o Rail executar com a CWD de acordo com Path é melhor servido com algo assim:

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

Isto é, inicie um shell para analisar a linha de comando, faça com que o shell altere a CWD e os trilhos de partida.

Bloqueando um gen_server

O Gen_Server está lá para serializar o processamento. Ou seja, processa uma mensagem após a outra. Não lida com todos eles simultaneamente. É sua razão para a existência não lidar com eles simultaneamente.

Você está (em relação a outros custos) fazendo algum cálculo muito caro no Gen_Server: Iniciando um processo externo que executa esse aplicativo Rails. É sua intenção ter no máximo um aplicativo Rails em execução a qualquer momento? (Ouvi falar de Ruby em trilhos que exigem toneladas de memória por processo, por isso pode ser uma decisão sensata).

Se você não precisar atualizar o Estado com quaisquer valores de uma chamada dispendiosa, como no seu código de exemplo, poderá usar uma chamada gen_server explícita: Responder/2.

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

E então você tem

rails_cmd(From, Path, Name, Args) ->
    Response = os:cmd(string:join(["cd", Path, "&&", "Rails", Name, Args], " ")),
    gen_server:reply(From, Response).
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top