Current section

Files

Jump to
shackle src shackle_utils.erl
Raw

src/shackle_utils.erl

-module(shackle_utils).
-include("shackle_internal.hrl").
-compile(inline).
-compile({inline_size, 512}).
%% public
-export([
cancel_timer/1,
client_setup/3,
lookup/3,
process_responses/2,
random/1,
random_element/1,
warning_msg/3,
reconnect_state/1,
reconnect_state_reset/1,
reply/3,
reply_all/2
]).
%% public
-spec cancel_timer(undefined | reference()) ->
ok.
cancel_timer(undefined) ->
ok;
cancel_timer(TimerRef) ->
erlang:cancel_timer(TimerRef).
-spec client_setup(client(), pool_name(), inet:socket()) ->
{ok, client_state()} | {error, term(), client_state()}.
client_setup(Client, PoolName, Socket) ->
{ok, ClientState} = Client:init(),
inet:setopts(Socket, [{active, false}]),
case Client:setup(Socket, ClientState) of
{ok, ClientState2} ->
inet:setopts(Socket, [{active, true}]),
{ok, ClientState2};
{error, Reason, ClientState2} ->
shackle_utils:warning_msg(PoolName,
"setup error: ~p", [Reason]),
{error, Reason, ClientState2}
end.
-spec lookup(atom(), [{atom(), term()}], term()) ->
term().
lookup(Key, List, Default) ->
case lists:keyfind(Key, 1, List) of
false -> Default;
{_, Value} -> Value
end.
-spec process_responses([response()], server_name()) ->
ok.
process_responses(Responses, Name) ->
lists:foreach(fun ({ExtRequestId, Reply}) ->
case shackle_queue:remove(Name, ExtRequestId) of
{ok, Cast, TimerRef} ->
erlang:cancel_timer(TimerRef),
reply(Name, Reply, Cast);
{error, not_found} ->
ok
end
end, Responses).
-spec random(pos_integer()) ->
non_neg_integer().
random(N) ->
granderl:uniform(N).
-spec random_element([term()]) ->
term().
random_element([X]) ->
X;
random_element([_|_] = List) ->
T = list_to_tuple(List),
element(random(tuple_size(T)), T).
-spec reconnect_state(client_options()) ->
undefined | reconnect_state().
reconnect_state(Options) ->
Reconnect = ?LOOKUP(reconnect, Options, ?DEFAULT_RECONNECT),
case Reconnect of
true ->
Max = ?LOOKUP(reconnect_time_max, Options,
?DEFAULT_RECONNECT_MAX),
Min = ?LOOKUP(reconnect_time_min, Options,
?DEFAULT_RECONNECT_MIN),
#reconnect_state {
min = Min,
max = Max
};
false ->
undefined
end.
-spec reconnect_state_reset(undefined | reconnect_state()) ->
undefined | reconnect_state().
reconnect_state_reset(undefined) ->
undefined;
reconnect_state_reset(#reconnect_state {} = ReconnectState) ->
ReconnectState#reconnect_state {
current = undefined
}.
-spec reply(server_name(), term(), undefined | cast()) ->
ok.
reply(Name, _Reply, #cast {pid = undefined}) ->
shackle_backlog:decrement(Name),
ok;
reply(Name, Reply, #cast {pid = Pid} = Cast) ->
shackle_backlog:decrement(Name),
Pid ! {Cast, Reply},
ok.
-spec reply_all(server_name(), term()) ->
ok.
reply_all(Name, Reply) ->
lists:foreach(fun ({Cast, TimerRef}) ->
erlang:cancel_timer(TimerRef),
reply(Name, Reply, Cast)
end, shackle_queue:clear(Name)).
-spec warning_msg(pool_name(), string(), [term()]) ->
ok.
warning_msg(Pool, Format, Data) ->
error_logger:warning_msg("[~p] " ++ Format, [Pool | Data]).