Skip to content

Commit

Permalink
Merge pull request #3157 from esl/mu-mam-rdbms-uses-dyn-dom
Browse files Browse the repository at this point in the history
Use HostType variable in mod_mam_rdbms_prefs/user
  • Loading branch information
chrzaszcz committed Jun 17, 2021
2 parents a40d5fa + 5ff96d7 commit 78880e6
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 383 deletions.
6 changes: 4 additions & 2 deletions src/gen_mod.erl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@

-type service_deps_list() :: [atom()].

-export_type([deps_list/0]).
-export_type([deps_list/0,
module_opts/0]).

-export([
% Modules start & stop
Expand Down Expand Up @@ -86,14 +87,15 @@
-type module_feature() :: atom().
-type domain_name() :: mongooseim:domain_name().
-type host_type() :: mongooseim:host_type().
-type module_opts() :: list().

%% -export([behaviour_info/1]).
%% behaviour_info(callbacks) ->
%% [{start, 2},
%% {stop, 1}];
%% behaviour_info(_Other) ->
%% undefined.
-callback start(HostType :: host_type(), Opts :: list()) -> any().
-callback start(HostType :: host_type(), Opts :: module_opts()) -> any().
-callback stop(HostType :: host_type()) -> any().
-callback supported_features() -> [module_feature()].
-callback config_spec() -> mongoose_config_spec:config_section().
Expand Down
2 changes: 1 addition & 1 deletion src/mam/mod_mam.erl
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ user_send_packet(Acc, From, To, Packet) ->
-spec filter_packet(Value :: fpacket() | drop) -> fpacket() | drop.
filter_packet(drop) ->
drop;
filter_packet({From, To = #jid{lserver = LServer}, Acc1, Packet}) ->
filter_packet({From, To, Acc1, Packet}) ->
?LOG_DEBUG(#{what => mam_user_receive_packet, acc => Acc1}),
HostType = mongoose_acc:host_type(Acc1),
{AmpEvent, PacketAfterArchive, Acc3} =
Expand Down
186 changes: 44 additions & 142 deletions src/mam/mod_mam_cache_user.erl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@

-record(state, {}).

%% @private
srv_name() ->
mod_mam_cache.

Expand All @@ -49,113 +48,65 @@ tbl_name_archive_id() ->
group_name() ->
mod_mam_cache.


-spec su_key(jid:jid()) -> jid:simple_bare_jid().
su_key(#jid{lserver = LServer, luser = LUser}) ->
{LServer, LUser}.


%% ----------------------------------------------------------------------
%% gen_mod callbacks
%% Starting and stopping functions for users' archives

-spec start(Host :: jid:server(), Opts :: list()) -> any().
start(Host, Opts) ->
start_server(Host),
case gen_mod:get_module_opt(Host, ?MODULE, pm, false) of
true ->
start_pm(Host, Opts);
false ->
ok
end,
case gen_mod:get_module_opt(Host, ?MODULE, muc, false) of
true ->
start_muc(Host, Opts);
false ->
ok
end.

-spec stop(Host :: jid:server()) -> any().
stop(Host) ->
stop_server(Host),
case gen_mod:get_module_opt(Host, ?MODULE, pm, false) of
true ->
stop_pm(Host);
false ->
ok
end,
case gen_mod:get_module_opt(Host, ?MODULE, muc, false) of
true ->
stop_muc(Host);
false ->
ok
end.

writer_child_spec() ->
{?MODULE,
{?MODULE, start_link, []},
permanent,
5000,
worker,
[?MODULE]}.

start_server(_Host) ->
%% TODO make per host server
supervisor:start_child(ejabberd_sup, writer_child_spec()).

stop_server(_Host) ->
-spec start(HostType :: mongooseim:host_type(), Opts :: gen_mod:module_opts()) -> ok.
start(HostType, _Opts) ->
start_server(),
ejabberd_hooks:add(hooks(HostType)),
ok.

%% ----------------------------------------------------------------------
%% Add hooks for mod_mam

-spec start_pm(jid:server(), list()) -> 'ok'.
start_pm(Host, _Opts) ->
ejabberd_hooks:add(mam_archive_id, Host, ?MODULE, cached_archive_id, 30),
ejabberd_hooks:add(mam_archive_id, Host, ?MODULE, store_archive_id, 70),
ejabberd_hooks:add(mam_remove_archive, Host, ?MODULE, remove_archive, 100),
-spec stop(HostType :: mongooseim:host_type()) -> ok.
stop(HostType) ->
ejabberd_hooks:delete(hooks(HostType)),
ok.

writer_child_spec() ->
MFA = {?MODULE, start_link, []},
{?MODULE, MFA, permanent, 5000, worker, [?MODULE]}.

-spec stop_pm(jid:server()) -> 'ok'.
stop_pm(Host) ->
ejabberd_hooks:delete(mam_archive_id, Host, ?MODULE, cached_archive_id, 30),
ejabberd_hooks:delete(mam_archive_id, Host, ?MODULE, store_archive_id, 70),
ejabberd_hooks:delete(mam_remove_archive, Host, ?MODULE, remove_archive, 100),
ok.

start_server() ->
%% TODO make per host server
supervisor:start_child(ejabberd_sup, writer_child_spec()).

%% ----------------------------------------------------------------------
%% Add hooks for mod_mam_muc
hooks(HostType) ->
PM = gen_mod:get_module_opt(HostType, ?MODULE, pm, false),
MUC = gen_mod:get_module_opt(HostType, ?MODULE, muc, false),
maybe_pm_hooks(PM, HostType) ++ maybe_muc_hooks(MUC, HostType).

-spec start_muc(jid:server(), list()) -> 'ok'.
start_muc(Host, _Opts) ->
ejabberd_hooks:add(mam_muc_archive_id, Host, ?MODULE, cached_archive_id, 30),
ejabberd_hooks:add(mam_muc_archive_id, Host, ?MODULE, store_archive_id, 70),
ejabberd_hooks:add(mam_muc_remove_archive, Host, ?MODULE, remove_archive, 100),
ok.
maybe_pm_hooks(true, HostType) -> pm_hooks(HostType);
maybe_pm_hooks(false, _HostType) -> [].

maybe_muc_hooks(true, HostType) -> muc_hooks(HostType);
maybe_muc_hooks(false, _HostType) -> [].

-spec stop_muc(jid:server()) -> 'ok'.
stop_muc(Host) ->
ejabberd_hooks:delete(mam_muc_archive_id, Host, ?MODULE, cached_archive_id, 30),
ejabberd_hooks:delete(mam_muc_archive_id, Host, ?MODULE, store_archive_id, 70),
ejabberd_hooks:delete(mam_muc_remove_archive, Host, ?MODULE, remove_archive, 100),
ok.
pm_hooks(HostType) ->
[{mam_archive_id, HostType, ?MODULE, cached_archive_id, 30},
{mam_archive_id, HostType, ?MODULE, store_archive_id, 70},
{mam_remove_archive, HostType, ?MODULE, remove_archive, 100}].

muc_hooks(HostType) ->
[{mam_muc_archive_id, HostType, ?MODULE, cached_archive_id, 30},
{mam_muc_archive_id, HostType, ?MODULE, store_archive_id, 70},
{mam_muc_remove_archive, HostType, ?MODULE, remove_archive, 100}].

%%====================================================================
%% API
%%====================================================================

-spec start_link() -> 'ignore' | {'error', _} | {'ok', pid()}.
-spec start_link() -> ignore | {error, _} | {ok, pid()}.
start_link() ->
gen_server:start_link({local, srv_name()}, ?MODULE, [], []).


-spec cached_archive_id('undefined', _Host :: jid:server(),
ArcJID :: jid:jid()) -> jid:user().
cached_archive_id(undefined, _Host, ArcJID) ->
-spec cached_archive_id(undefined, HostType :: mongooseim:host_type(),
ArcJID :: jid:jid()) -> mod_mam:archive_id().
cached_archive_id(undefined, _HostType, ArcJID) ->
case lookup_archive_id(ArcJID) of
not_found ->
put(mam_not_cached_flag, true),
Expand All @@ -164,53 +115,46 @@ cached_archive_id(undefined, _Host, ArcJID) ->
UserID
end.


-spec store_archive_id(jid:user(), jid:server(), jid:jid())
-> jid:user().
store_archive_id(UserID, _Host, ArcJID) ->
-spec store_archive_id(mod_mam:archive_id(), mongooseim:host_type(), jid:jid())
-> mod_mam:archive_id().
store_archive_id(UserID, _HostType, ArcJID) ->
maybe_cache_archive_id(ArcJID, UserID),
UserID.


%% #rh
-spec remove_archive(Acc :: map(), _Host :: jid:server(),
_UserID :: jid:user(),
ArcJID :: jid:jid()) -> map().
remove_archive(Acc, _Host, _UserID, ArcJID) ->
-spec remove_archive(Acc :: map(), HostType :: mongooseim:host_type(),
UserID :: mod_mam:archive_id(), ArcJID :: jid:jid()) -> map().
remove_archive(Acc, _HostType, _UserID, ArcJID) ->
clean_cache(ArcJID),
Acc.

%%====================================================================
%% Internal functions
%%====================================================================

-spec maybe_cache_archive_id(jid:jid(), jid:user()) -> jid:user() | ok.
-spec maybe_cache_archive_id(jid:jid(), mod_mam:archive_id()) -> ok.
maybe_cache_archive_id(ArcJID, UserID) ->
case erase(mam_not_cached_flag) of
undefined ->
UserID;
ok;
true ->
cache_archive_id(ArcJID, UserID)
end.


%% @doc Put the user id into cache.
%% @private
-spec cache_archive_id(jid:jid(), jid:user()) -> ok.
-spec cache_archive_id(jid:jid(), mod_mam:archive_id()) -> ok.
cache_archive_id(ArcJID, UserID) ->
gen_server:call(srv_name(), {cache_archive_id, ArcJID, UserID}).


-spec lookup_archive_id(jid:jid()) -> jid:user() | not_found.
-spec lookup_archive_id(jid:jid()) -> mod_mam:archive_id() | not_found.
lookup_archive_id(ArcJID) ->
try
ets:lookup_element(tbl_name_archive_id(), su_key(ArcJID), 2)
catch error:badarg ->
not_found
end.


-spec clean_cache(jid:jid()) -> 'ok'.
-spec clean_cache(jid:jid()) -> ok.
clean_cache(ArcJID) ->
%% Send a broadcast message.
case pg2:get_members(group_name()) of
Expand All @@ -225,13 +169,6 @@ clean_cache(ArcJID) ->
%% gen_server callbacks
%%====================================================================

%%--------------------------------------------------------------------
%% Function: init(Args) -> {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
init([]) ->
pg2:create(group_name()),
pg2:join(group_name(), self()),
Expand All @@ -241,59 +178,24 @@ init([]) ->
ets:new(tbl_name_archive_id(), TOpts),
{ok, #state{}}.

%%--------------------------------------------------------------------
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} |
%% {stop, Reason, State}
%% Description: Handling call messages
%%--------------------------------------------------------------------
handle_call({cache_archive_id, ArcJID, UserID}, _From, State) ->
ets:insert(tbl_name_archive_id(), {su_key(ArcJID), UserID}),
{reply, ok, State}.


%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% Description: Handling cast messages
%%--------------------------------------------------------------------

handle_cast({remove_user, ArcJID}, State) ->
ets:delete(tbl_name_archive_id(), su_key(ArcJID)),
{noreply, State};
handle_cast(Msg, State) ->
?UNEXPECTED_CAST(Msg),
{noreply, State}.

%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------

handle_info(Msg, State) ->
?UNEXPECTED_INFO(Msg),
{noreply, State}.

%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
%% Description: This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any necessary
%% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(_Reason, _State) ->
ok.

%%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
%% Description: Convert process state when code is changed
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.

Loading

0 comments on commit 78880e6

Please sign in to comment.