diff options
author | Loïc Hoguin <[email protected]> | 2019-05-13 13:18:01 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2019-05-13 13:18:01 +0200 |
commit | 3aa7168404e62f9ea9e290380b93569eff4372a8 (patch) | |
tree | ab8cb6f89c2e5e3abb5cb27d34b9b902b427625f | |
parent | cfd702a716f834c431abd46532e8cfa4debd1468 (diff) | |
download | gun-3aa7168404e62f9ea9e290380b93569eff4372a8.tar.gz gun-3aa7168404e62f9ea9e290380b93569eff4372a8.tar.bz2 gun-3aa7168404e62f9ea9e290380b93569eff4372a8.zip |
Add the disconnect event callback
-rw-r--r-- | src/gun.erl | 13 | ||||
-rw-r--r-- | src/gun_default_event_h.erl | 4 | ||||
-rw-r--r-- | src/gun_event.erl | 9 | ||||
-rw-r--r-- | test/event_SUITE.erl | 20 |
4 files changed, 42 insertions, 4 deletions
diff --git a/src/gun.erl b/src/gun.erl index e958d2e..44dbdeb 100644 --- a/src/gun.erl +++ b/src/gun.erl @@ -1006,7 +1006,8 @@ commands([{switch_protocol, Protocol, _ProtoState0}|Tail], disconnect(State=#state{owner=Owner, opts=Opts, socket=Socket, transport=Transport, - protocol=Protocol, protocol_state=ProtoState}, Reason) -> + protocol=Protocol, protocol_state=ProtoState, + event_handler=EventHandler, event_handler_state=EventHandlerState0}, Reason) -> Protocol:close(Reason, ProtoState), %% @todo Need a special state for orderly shutdown of a connection. Transport:close(Socket), @@ -1015,14 +1016,20 @@ disconnect(State=#state{owner=Owner, opts=Opts, %% @todo Stop keepalive timeout, flush message. {KilledStreams, UnprocessedStreams} = Protocol:down(ProtoState), Owner ! {gun_down, self(), Protocol:name(), Reason, KilledStreams, UnprocessedStreams}, + %% Trigger the disconnect event. + DisconnectEvent = #{ + reason => Reason + }, + EventHandlerState = EventHandler:disconnect(DisconnectEvent, EventHandlerState0), Retry = maps:get(retry, Opts, 5), case Retry of 0 -> - {stop, {shutdown, Reason}}; + {stop, {shutdown, Reason}, State#state{event_handler_state=EventHandlerState}}; _ -> {next_state, not_connected, keepalive_cancel(State#state{socket=undefined, - protocol=undefined, protocol_state=undefined}), + protocol=undefined, protocol_state=undefined, + event_handler_state=EventHandlerState}), {next_event, internal, {retries, Retry - 1}}} end. diff --git a/src/gun_default_event_h.erl b/src/gun_default_event_h.erl index e242e84..f234dda 100644 --- a/src/gun_default_event_h.erl +++ b/src/gun_default_event_h.erl @@ -18,6 +18,7 @@ -export([init/2]). -export([connect_start/2]). -export([connect_end/2]). +-export([disconnect/2]). init(_EventData, State) -> State. @@ -27,3 +28,6 @@ connect_start(_EventData, State) -> connect_end(_EventData, State) -> State. + +disconnect(_EventData, State) -> + State. diff --git a/src/gun_event.erl b/src/gun_event.erl index fffcafe..bb541ed 100644 --- a/src/gun_event.erl +++ b/src/gun_event.erl @@ -43,6 +43,14 @@ -callback connect_start(connect_event(), State) -> State. -callback connect_end(connect_event(), State) -> State. +%% disconnect. + +-type disconnect_event() :: #{ + reason := normal | closed | {error, any()} +}. + +-callback disconnect(disconnect_event(), State) -> State. + %% @todo domain_lookup_start %% @todo domain_lookup_end %% @todo tls_handshake_start @@ -50,7 +58,6 @@ %% @todo origin_changed %% @todo transport_changed %% @todo protocol_changed -%% @todo disconnected %% @todo terminate %% @todo stream_start %% @todo stream_end diff --git a/test/event_SUITE.erl b/test/event_SUITE.erl index 383ac46..50a1ce2 100644 --- a/test/event_SUITE.erl +++ b/test/event_SUITE.erl @@ -20,6 +20,7 @@ -import(ct_helper, [config/2]). -import(ct_helper, [doc/1]). +-import(gun_test, [init_origin/1]). all() -> ct_helper:all(?MODULE). @@ -99,6 +100,21 @@ connect_end_ok(Config) -> } = do_receive_event(connect_end), gun:close(Pid). +disconnect(_) -> + doc("Confirm that the disconnect event callback is called on disconnect."), + Self = self(), + Opts = #{event_handler => {?MODULE, Self}}, + {ok, OriginPid, OriginPort} = init_origin(tcp), + {ok, Pid} = gun:open("localhost", OriginPort, Opts), + {ok, http} = gun:await_up(Pid), + %% We make the origin exit to trigger a disconnect. + unlink(OriginPid), + exit(OriginPid, shutdown), + #{ + reason := closed + } = do_receive_event(disconnect), + gun:close(Pid). + %% Internal. do_receive_event(Event) -> @@ -122,3 +138,7 @@ connect_start(EventData, Pid) -> connect_end(EventData, Pid) -> Pid ! {?FUNCTION_NAME, EventData}, Pid. + +disconnect(EventData, Pid) -> + Pid ! {?FUNCTION_NAME, EventData}, + Pid. |