Current section

Files

Jump to
maildir_commander src mc_pop_manager.erl
Raw

src/mc_pop_manager.erl

%% The module gate keep the pop activities for one User/Host combo
%%
-module(mc_pop_manager).
-behaviour(gen_server).
-include_lib("kernel/include/logger.hrl").
%% apis
-export([start_link/0]).
-export([pop_all/3, list/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
%% from user
-spec pop_all(list(), list(), list()) -> ok.
pop_all(User, Pass, Host) ->
gen_server:cast(?MODULE, {pop_all, User, Pass, Host}).
-spec list() -> list().
list() ->
gen_server:call(?MODULE, list).
%% server side api
init([]) ->
process_flag(trap_exit, true),
{ok, #{}}.
handle_call(list, _From, State) ->
{reply, maps:keys(State), State}.
handle_cast({pop_all, User, Pass, Host}, State) ->
case maps:get({User, Host}, State, undefined) of
undefined ->
Pid = spawn_link(mc_popper, pop_all, [User, Pass, Host]),
{noreply, State#{{User, Host} => Pid}};
Pid ->
?LOG_DEBUG("POP of ~ts@~ts is still going on: ~w", [User, Host, Pid]),
{noreply, State}
end.
handle_info({'EXIT', Pid, normal}, State) ->
Key = find_key(Pid, State),
{noreply, maps:remove(Key, State)};
handle_info({'EXIT', Pid, Reason}, State) ->
Key = {User, Host} = find_key(Pid, State),
?LOG_WARNING("POP of ~ts@~ts crashed: ~w", [User, Host, Reason]),
{noreply, maps:remove(Key, State)}.
find_key(Value, Map) -> find_key(Value, maps:keys(Map), Map).
find_key(_Value, [], _Map) -> undefined;
find_key(Value, [Head | Tail], Map) ->
case maps:get(Head, Map, undefined) of
Value -> Head;
_ -> find_key(Value, Tail, Map)
end.