4141 #{async => boolean (),
4242 async_mode => binary | sse ,
4343 handle_event => fun ((fin | nofin , reference (), binary ()) -> any ()),
44- timeout => timeout ()}. % % Default 5000 ms
44+ timeout => timeout (), % % Default 5000 ms
45+ allow_reconnect => boolean ()}. % % Default true
4546-type response () ::
4647 #{status_code => integer (),
4748 headers => proplists :proplist (),
@@ -241,13 +242,15 @@ request(Pid, get, Uri, Headers0, Body, Options) ->
241242 async := IsAsync ,
242243 async_mode := AsyncMode ,
243244 headers := Headers ,
244- timeout := Timeout } =
245+ timeout := Timeout ,
246+ allow_reconnect := AllowReconnect
247+ } =
245248 process_options (Options , Headers0 , get ),
246249
247250 Event =
248251 case IsAsync of
249252 true ->
250- {get_async , {HandleEvent , AsyncMode }, {Uri , Headers , Body }};
253+ {get_async , {HandleEvent , AsyncMode , AllowReconnect }, {Uri , Headers , Body }};
251254 false ->
252255 {get , {Uri , Headers , Body }}
253256 end ,
@@ -320,7 +323,9 @@ parse_event(EventBin) ->
320323 pid => pid () | undefined ,
321324 responses => queue :queue () | undefined ,
322325 status_code => integer () | undefined ,
323- stream => reference () | undefined }.
326+ stream => reference () | undefined ,
327+ allow_reconnect => boolean ()
328+ }.
324329
325330% % @private
326331-spec callback_mode () -> state_functions .
@@ -392,12 +397,17 @@ handle_info({gun_up, Pid, _Protocol}, StateName, StateData = #{pid := Pid}) ->
392397 {next_state , StateName , StateData };
393398handle_info ({gun_down , Pid , Protocol , Reason , KilledStreams },
394399 _StateName ,
395- StateData = #{pid := Pid }) ->
396- error_logger :warning_msg (" ~p connection down on ~p : ~p (Killed: ~p )" ,
397- [Protocol , Pid , Reason , KilledStreams ]),
398- gun :shutdown (Pid ),
399- CleanStateData = clean_state_data (StateData ),
400- {next_state , down , CleanStateData };
400+ StateData = #{pid := Pid , allow_reconnect := AllowReconnect }) ->
401+ error_logger :warning_msg (" ~p connection down on ~p : ~p (Killed: ~p ) (AllowReconnect: ~p )" ,
402+ [Protocol , Pid , Reason , KilledStreams , AllowReconnect ]),
403+ case AllowReconnect of
404+ true ->
405+ gun :shutdown (Pid ),
406+ CleanStateData = clean_state_data (StateData ),
407+ {next_state , down , CleanStateData };
408+ false ->
409+ keep_state_and_data
410+ end ;
401411handle_info (Event , StateName , StateData ) ->
402412 Module = ? MODULE ,
403413 % forward messages to state machine
@@ -450,7 +460,7 @@ at_rest(cast, {gun_down, _Args, _From}, StateData = #{pid := Pid}) ->
450460 CleanStateData = clean_state_data (StateData ),
451461 {next_state , down , CleanStateData };
452462at_rest (cast ,
453- {get_async , {HandleEvent , AsyncMode }, Args , From },
463+ {get_async , {HandleEvent , AsyncMode , AllowReconnect }, Args , From },
454464 StateData = #{pid := Pid }) ->
455465 StreamRef = do_http_verb (get , Pid , Args ),
456466 CleanStateData = clean_state_data (StateData ),
@@ -460,7 +470,8 @@ at_rest(cast,
460470 stream => StreamRef ,
461471 handle_event => HandleEvent ,
462472 async => true ,
463- async_mode => AsyncMode },
473+ async_mode => AsyncMode ,
474+ allow_reconnect => AllowReconnect },
464475 {next_state , wait_response , NewStateData };
465476at_rest (cast , {HttpVerb , {_ , _ , Body } = Args , From }, StateData = #{pid := Pid }) ->
466477 StreamRef = do_http_verb (HttpVerb , Pid , Args ),
@@ -641,6 +652,7 @@ clean_state_data() ->
641652clean_state_data (StateData ) ->
642653 Responses = maps :get (responses , StateData , queue :new ()),
643654 Requests = maps :get (pending_requests , StateData , queue :new ()),
655+ AllowReconnect = maps :get (allow_reconnect , StateData , true ),
644656 #{pid => undefined ,
645657 stream => undefined ,
646658 handle_event => undefined ,
@@ -652,7 +664,8 @@ clean_state_data(StateData) ->
652664 async => false ,
653665 async_mode => binary ,
654666 buffer => <<" " >>,
655- pending_requests => Requests }.
667+ pending_requests => Requests ,
668+ allow_reconnect => AllowReconnect }.
656669
657670% % @private
658671-spec do_http_verb (http_verb (), pid (), tuple ()) -> reference ().
@@ -711,6 +724,7 @@ process_options(Options, Headers0, HttpVerb) ->
711724 Async = maps :get (async , Options , false ),
712725 AsyncMode = maps :get (async_mode , Options , binary ),
713726 Timeout = maps :get (timeout , Options , 5000 ),
727+ AllowReconnect = maps :get (allow_reconnect , Options , true ),
714728 case {Async , HttpVerb } of
715729 {true , get } ->
716730 ok ;
@@ -723,7 +737,8 @@ process_options(Options, Headers0, HttpVerb) ->
723737 async => Async ,
724738 async_mode => AsyncMode ,
725739 headers => Headers ,
726- timeout => Timeout }.
740+ timeout => Timeout ,
741+ allow_reconnect => AllowReconnect }.
727742
728743% % @private
729744-spec basic_auth_header (headers ()) -> proplists :proplist ().
@@ -809,8 +824,8 @@ enqueue_work_or_stop(_StateName, Event, From, StateData, Timeout) ->
809824
810825% % @private
811826-spec create_work ({atom (), list ()}, gen_statem :from ()) -> not_work | {ok , work ()}.
812- create_work ({M = get_async , {HandleEvent , AsyncMode }, Args }, From ) ->
813- {ok , {M , {HandleEvent , AsyncMode }, Args , From }};
827+ create_work ({M = get_async , {HandleEvent , AsyncMode , AllowReconnect }, Args }, From ) ->
828+ {ok , {M , {HandleEvent , AsyncMode , AllowReconnect }, Args , From }};
814829create_work ({M , Args }, From )
815830 when M == get
816831 orelse M == post
0 commit comments