mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Add a terminate event to the tracer and more tests
This commit is contained in:
parent
af58babd94
commit
da304799fe
2 changed files with 67 additions and 8 deletions
|
@ -80,7 +80,7 @@ init_tracer(StreamID, Req, Opts=#{tracer_match_specs := List, tracer_callback :=
|
|||
start_tracer(StreamID, Req, Opts)
|
||||
end;
|
||||
%% When the options tracer_match_specs or tracer_callback
|
||||
%% arenot provided we do not enable tracing.
|
||||
%% are not provided we do not enable tracing.
|
||||
init_tracer(_, _, _) ->
|
||||
no_tracing.
|
||||
|
||||
|
@ -138,6 +138,8 @@ start_tracer(StreamID, Req, Opts) ->
|
|||
|
||||
-spec tracer_process(_, _, _) -> no_return().
|
||||
tracer_process(StreamID, Req=#{pid := Parent}, Opts=#{tracer_callback := Fun}) ->
|
||||
%% This is necessary because otherwise the tracer could stop
|
||||
%% before it has finished processing the events in its queue.
|
||||
process_flag(trap_exit, true),
|
||||
State = Fun(init, {StreamID, Req, Opts}),
|
||||
tracer_loop(Parent, Fun, State).
|
||||
|
@ -148,7 +150,7 @@ tracer_loop(Parent, Fun, State) ->
|
|||
Fun(Msg, State),
|
||||
tracer_loop(Parent, Fun, State);
|
||||
{'EXIT', Parent, Reason} ->
|
||||
exit(Reason);
|
||||
tracer_terminate(Reason, Fun, State);
|
||||
{system, From, Request} ->
|
||||
sys:handle_system_msg(Request, From, Parent, ?MODULE, [], {Fun, State});
|
||||
Msg ->
|
||||
|
@ -157,6 +159,10 @@ tracer_loop(Parent, Fun, State) ->
|
|||
tracer_loop(Parent, Fun, State)
|
||||
end.
|
||||
|
||||
tracer_terminate(Reason, Fun, State) ->
|
||||
_ = Fun(terminate, State),
|
||||
exit(Reason).
|
||||
|
||||
%% System callbacks.
|
||||
|
||||
-spec system_continue(pid(), _, {fun(), any()}) -> no_return().
|
||||
|
@ -164,8 +170,8 @@ system_continue(Parent, _, {Fun, State}) ->
|
|||
tracer_loop(Parent, Fun, State).
|
||||
|
||||
-spec system_terminate(any(), _, _, _) -> no_return().
|
||||
system_terminate(Reason, _, _, _) ->
|
||||
exit(Reason).
|
||||
system_terminate(Reason, _, _, {Fun, State}) ->
|
||||
tracer_terminate(Reason, Fun, State).
|
||||
|
||||
-spec system_code_change(Misc, _, _, _) -> {ok, Misc} when Misc::any().
|
||||
system_code_change(Misc, _, _, _) ->
|
||||
|
|
|
@ -93,16 +93,69 @@ do_get(Path, Config) ->
|
|||
{ok, _Body} = gun:await_body(ConnPid, Ref),
|
||||
gun:close(ConnPid).
|
||||
|
||||
%% We only care about cowboy_req:reply/4 calls.
|
||||
%% We only care about cowboy_req:reply/4 calls and init/terminate events.
|
||||
do_tracer_callback(Pid) ->
|
||||
fun
|
||||
(init, _) -> undefined;
|
||||
(Event={trace_ts, _, call, {cowboy_req, reply, _}, _}, State) -> Pid ! Event, State;
|
||||
(_, State) -> State
|
||||
(Event, _) when Event =:= init; Event =:= terminate ->
|
||||
Pid ! Event,
|
||||
undefined;
|
||||
(Event={trace_ts, _, call, {cowboy_req, reply, _}, _}, State) ->
|
||||
Pid ! Event,
|
||||
State;
|
||||
(_, State) ->
|
||||
State
|
||||
end.
|
||||
|
||||
%% Tests.
|
||||
|
||||
init(Config) ->
|
||||
doc("Ensure the init event is triggered."),
|
||||
Ref = config(ref, Config),
|
||||
Opts = ranch:get_protocol_options(Ref),
|
||||
ranch:set_protocol_options(Ref, Opts#{
|
||||
tracer_callback => do_tracer_callback(self()),
|
||||
tracer_match_specs => [fun(_,_,_) -> true end]
|
||||
}),
|
||||
do_get("/", Config),
|
||||
receive
|
||||
init ->
|
||||
ok
|
||||
after 100 ->
|
||||
error(timeout)
|
||||
end.
|
||||
|
||||
terminate(Config) ->
|
||||
doc("Ensure the terminate event is triggered."),
|
||||
Ref = config(ref, Config),
|
||||
Opts = ranch:get_protocol_options(Ref),
|
||||
ranch:set_protocol_options(Ref, Opts#{
|
||||
tracer_callback => do_tracer_callback(self()),
|
||||
tracer_match_specs => [fun(_,_,_) -> true end]
|
||||
}),
|
||||
do_get("/", Config),
|
||||
receive
|
||||
terminate ->
|
||||
ok
|
||||
after 100 ->
|
||||
error(timeout)
|
||||
end.
|
||||
|
||||
empty(Config) ->
|
||||
doc("Empty match specs unconditionally enable tracing."),
|
||||
Ref = config(ref, Config),
|
||||
Opts = ranch:get_protocol_options(Ref),
|
||||
ranch:set_protocol_options(Ref, Opts#{
|
||||
tracer_callback => do_tracer_callback(self()),
|
||||
tracer_match_specs => []
|
||||
}),
|
||||
do_get("/", Config),
|
||||
receive
|
||||
{trace_ts, _, call, {cowboy_req, reply, [200, _, _, _]}, _} ->
|
||||
ok
|
||||
after 100 ->
|
||||
error(timeout)
|
||||
end.
|
||||
|
||||
predicate_true(Config) ->
|
||||
doc("Predicate function returns true, unconditionally enable tracing."),
|
||||
Ref = config(ref, Config),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue