mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Add initial support for system messages in cowboy_loop
This commit is contained in:
parent
21c9c66971
commit
4d5174632c
3 changed files with 38 additions and 7 deletions
|
@ -19,6 +19,10 @@
|
||||||
-export([upgrade/5]).
|
-export([upgrade/5]).
|
||||||
-export([loop/4]).
|
-export([loop/4]).
|
||||||
|
|
||||||
|
-export([system_continue/3]).
|
||||||
|
-export([system_terminate/4]).
|
||||||
|
-export([system_code_change/4]).
|
||||||
|
|
||||||
-callback init(Req, any())
|
-callback init(Req, any())
|
||||||
-> {ok | module(), Req, any()}
|
-> {ok | module(), Req, any()}
|
||||||
| {module(), Req, any(), any()}
|
| {module(), Req, any(), any()}
|
||||||
|
@ -49,8 +53,18 @@ upgrade(Req, Env, Handler, HandlerState, hibernate) ->
|
||||||
-> {ok, Req, Env} | {suspend, ?MODULE, loop, [any()]}
|
-> {ok, Req, Env} | {suspend, ?MODULE, loop, [any()]}
|
||||||
when Req::cowboy_req:req(), Env::cowboy_middleware:env().
|
when Req::cowboy_req:req(), Env::cowboy_middleware:env().
|
||||||
%% @todo Handle system messages.
|
%% @todo Handle system messages.
|
||||||
loop(Req, Env, Handler, HandlerState) ->
|
loop(Req=#{pid := Parent}, Env, Handler, HandlerState) ->
|
||||||
receive
|
receive
|
||||||
|
%% System messages.
|
||||||
|
{'EXIT', Parent, Reason} ->
|
||||||
|
terminate(Req, Env, Handler, HandlerState, Reason);
|
||||||
|
{system, From, Request} ->
|
||||||
|
sys:handle_system_msg(Request, From, Parent, ?MODULE, [],
|
||||||
|
{Req, Env, Handler, HandlerState});
|
||||||
|
%% Calls from supervisor module.
|
||||||
|
{'$gen_call', From, Call} ->
|
||||||
|
cowboy_children:handle_supervisor_call(Call, From, [], ?MODULE),
|
||||||
|
loop(Req, Env, Handler, HandlerState);
|
||||||
Message ->
|
Message ->
|
||||||
call(Req, Env, Handler, HandlerState, Message)
|
call(Req, Env, Handler, HandlerState, Message)
|
||||||
end.
|
end.
|
||||||
|
@ -74,3 +88,21 @@ suspend(Req, Env, Handler, HandlerState) ->
|
||||||
terminate(Req, Env, Handler, HandlerState, Reason) ->
|
terminate(Req, Env, Handler, HandlerState, Reason) ->
|
||||||
Result = cowboy_handler:terminate(Reason, Req, HandlerState, Handler),
|
Result = cowboy_handler:terminate(Reason, Req, HandlerState, Handler),
|
||||||
{ok, Req, Env#{result => Result}}.
|
{ok, Req, Env#{result => Result}}.
|
||||||
|
|
||||||
|
%% System callbacks.
|
||||||
|
|
||||||
|
-spec system_continue(_, _, {Req, Env, module(), any()})
|
||||||
|
-> {ok, Req, Env} | {suspend, ?MODULE, loop, [any()]}
|
||||||
|
when Req::cowboy_req:req(), Env::cowboy_middleware:env().
|
||||||
|
system_continue(_, _, {Req, Env, Handler, HandlerState}) ->
|
||||||
|
loop(Req, Env, Handler, HandlerState).
|
||||||
|
|
||||||
|
-spec system_terminate(any(), _, _, {Req, Env, module(), any()})
|
||||||
|
-> {ok, Req, Env} when Req::cowboy_req:req(), Env::cowboy_middleware:env().
|
||||||
|
system_terminate(Reason, _, _, {Req, Env, Handler, HandlerState}) ->
|
||||||
|
terminate(Req, Env, Handler, HandlerState, Reason).
|
||||||
|
|
||||||
|
-spec system_code_change(Misc, _, _, _) -> {ok, Misc}
|
||||||
|
when Misc::{cowboy_req:req(), cowboy_middleware:env(), module(), any()}.
|
||||||
|
system_code_change(Misc, _, _, _) ->
|
||||||
|
{ok, Misc}.
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
init(Req, _) ->
|
init(Req, _) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
erlang:send_after(500, self(), timeout),
|
erlang:send_after(500, self(), timeout),
|
||||||
{cowboy_loop, Req, undefined, hibernate}.
|
{cowboy_loop, Req, undefined}.
|
||||||
|
|
||||||
info(timeout, Req, State) ->
|
info(timeout, Req, State) ->
|
||||||
%% Send an unused status code to make sure there's no
|
%% Send an unused status code to make sure there's no
|
||||||
|
@ -19,5 +19,5 @@ info(timeout, Req, State) ->
|
||||||
info(_, Req, State) ->
|
info(_, Req, State) ->
|
||||||
{ok, Req, State}.
|
{ok, Req, State}.
|
||||||
|
|
||||||
terminate({crash, _, _}, _, _) ->
|
terminate(_, _, _) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -400,9 +400,8 @@ trap_exit_parent_exit_loop(Config) ->
|
||||||
Parent = do_get_remote_pid_tcp(Socket),
|
Parent = do_get_remote_pid_tcp(Socket),
|
||||||
[{_, Pid, _, _}] = supervisor:which_children(Parent),
|
[{_, Pid, _, _}] = supervisor:which_children(Parent),
|
||||||
Pid ! {'EXIT', Parent, shutdown},
|
Pid ! {'EXIT', Parent, shutdown},
|
||||||
%% We're getting a 500 because the process exited in an unexpected way
|
%% We exit normally but didn't send a response.
|
||||||
%% from Cowboy's point of view.
|
{ok, "HTTP/1.1 204 "} = gen_tcp:recv(Socket, 13, 1000),
|
||||||
{ok, "HTTP/1.1 500 "} = gen_tcp:recv(Socket, 13, 1000),
|
|
||||||
false = is_process_alive(Pid),
|
false = is_process_alive(Pid),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
@ -483,7 +482,7 @@ trap_exit_other_exit_loop(Config) ->
|
||||||
timer:sleep(100),
|
timer:sleep(100),
|
||||||
Parent = do_get_remote_pid_tcp(Socket),
|
Parent = do_get_remote_pid_tcp(Socket),
|
||||||
[{_, Pid, _, _}] = supervisor:which_children(Parent),
|
[{_, Pid, _, _}] = supervisor:which_children(Parent),
|
||||||
Pid ! {'EXIT', Parent, shutdown},
|
Pid ! {'EXIT', self(), shutdown},
|
||||||
%% The process stays alive.
|
%% The process stays alive.
|
||||||
{ok, "HTTP/1.1 299 "} = gen_tcp:recv(Socket, 13, 1000),
|
{ok, "HTTP/1.1 299 "} = gen_tcp:recv(Socket, 13, 1000),
|
||||||
true = is_process_alive(Pid),
|
true = is_process_alive(Pid),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue