Stratus3D
Stratus3D

Reputation: 4916

Erlang stopping application doesn't end all processes?

When I stop an Erlang application that I built, the cowboy listener process stays alive, continuing to handle requests. In the gen_server that I wrote I start a server on init. As you can see below:

init([Port]) ->
    Dispatch = cowboy_router:compile([
        {'_', [
                    {"/custom/[...]", ?MODULE, []},
                    % Serve index.html as default file
                    % Serve entire directory
                    {"/[...]", cowboy_static, {priv_dir,
                                               app, "www"}}
              ]}
        ]),
    Name = custom_name,
    {ok, Pid} = cowboy:start_http(Name, 100,
                  [{port, Port}],
                   [{env, [{dispatch, Dispatch}]}]),
    {ok, #state{handler_pid = Pid}}.

This starts the cowboy http server, which uses cowboy_static to server some stuff in the priv/app/ dir and the current module to handle custom stuff (module implements all the cowboy http handle callbacks). It takes the pid returned from the call and assigns it to handler_pid in the state record. This all works. However when I startup the application containing this module (which works) and then I stop it. All processes end (at least the ones in my application). The custom handler (which is implemented in the same module as the gen_server) no longer works. But the cowboy_static handle continues to handle requests. It continues to serve static files until I kill the node. I tried fixing this by adding this to the gen_server:

terminate(_Reason, State) ->
    exit(State#state.handler_pid, normal),
    cowboy:stop_listener(listener_name()),
    ok.

But nothing changes. The cowboy_static handler continues to serve static files.

Questions:

Thanks in advance!

Upvotes: 2

Views: 903

Answers (2)

mikea
mikea

Reputation: 815

You should fix 3 things:

  • the symbol in start_http(Name, ...) and stop_listener(Name) should match.
  • trap exit in service init: process_flag(trap_exit, true)
  • remove exit call from terminate.

Upvotes: 2

Pascal
Pascal

Reputation: 14042

I don't think it is really important, generally you use one node/VM per application (in fact a bunch of erlang application working together, but I haven't a better word). But I think you can stop the server using application:stop(cowboy), application:stop(ranch).

Upvotes: 4

Related Questions