From d8205f0d595a25af96347c0f81c3a696c1febc20 Mon Sep 17 00:00:00 2001 From: Mikhail Uvarov Date: Wed, 16 Jun 2021 16:36:56 +0200 Subject: [PATCH 1/7] Use HostType variable names in mod_mam_utils --- src/mam/mod_mam_utils.erl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/mam/mod_mam_utils.erl b/src/mam/mod_mam_utils.erl index 2d42c2fc3d4..e3586f079bd 100644 --- a/src/mam/mod_mam_utils.erl +++ b/src/mam/mod_mam_utils.erl @@ -685,18 +685,19 @@ find_field([], _Name) -> field_to_value(FieldEl) -> exml_query:path(FieldEl, [{element, <<"value">>}, cdata], <<>>). --spec message_form(Mod :: mod_mam | mod_mam_muc, Host :: jid:lserver(), binary()) -> +-spec message_form(Mod :: mod_mam | mod_mam_muc, + HostType :: mongooseim:host_type(), binary()) -> exml:element(). -message_form(Module, Host, MamNs) -> +message_form(Module, HostType, MamNs) -> SubEl = #xmlel{name = <<"x">>, attrs = [{<<"xmlns">>, <<"jabber:x:data">>}, {<<"type">>, <<"form">>}], - children = message_form_fields(Module, Host, MamNs)}, + children = message_form_fields(Module, HostType, MamNs)}, result_query(SubEl, MamNs). -message_form_fields(Mod, Host, MamNs) -> +message_form_fields(Mod, HostType, MamNs) -> TextSearch = - case has_full_text_search(Mod, Host) of + case has_full_text_search(Mod, HostType) of true -> [form_field(<<"text-single">>, <<"full-text-search">>)]; false -> [] end, @@ -751,10 +752,11 @@ normalize_search_text(Text, WordSeparator) -> Re2 = re:replace(Re1, "\s+", unicode:characters_to_list(WordSeparator), ReOpts), unicode:characters_to_binary(Re2). --spec packet_to_search_body(Module :: mod_mam | mod_mam_muc, Host :: jid:server(), +-spec packet_to_search_body(Module :: mod_mam | mod_mam_muc, + HostType :: mongooseim:host_type(), Packet :: exml:element()) -> binary(). -packet_to_search_body(Module, Host, Packet) -> - SearchEnabled = has_full_text_search(Module, Host), +packet_to_search_body(Module, HostType, Packet) -> + SearchEnabled = has_full_text_search(Module, HostType), packet_to_search_body(SearchEnabled, Packet). -spec packet_to_search_body(Enabled :: boolean(), From aa6472354a91fd3a2239405ebb809407f7d0a2bf Mon Sep 17 00:00:00 2001 From: Mikhail Uvarov Date: Wed, 16 Jun 2021 16:37:37 +0200 Subject: [PATCH 2/7] Remove unused LServer variable in mod_mam --- src/mam/mod_mam.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mam/mod_mam.erl b/src/mam/mod_mam.erl index 25b6d68ec9e..1a8310cd679 100644 --- a/src/mam/mod_mam.erl +++ b/src/mam/mod_mam.erl @@ -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} = From f8d7c4cf6f1fd5c5b99e684e5570f6a592030eaf Mon Sep 17 00:00:00 2001 From: Mikhail Uvarov Date: Wed, 16 Jun 2021 17:01:49 +0200 Subject: [PATCH 3/7] Add gen_mod:module_opts() type --- src/gen_mod.erl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 7e179f2746c..7299c553737 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -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 @@ -86,6 +87,7 @@ -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) -> @@ -93,7 +95,7 @@ %% {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(). From 3a9aa710e238a7a34104aa739fa5ec1820364aea Mon Sep 17 00:00:00 2001 From: Mikhail Uvarov Date: Wed, 16 Jun 2021 17:02:21 +0200 Subject: [PATCH 4/7] Refactor hook starting in mod_mam_rdbms_user Use HostType variable name in mod_mam_rdbms_user --- src/mam/mod_mam_rdbms_user.erl | 151 +++++++++------------------------ 1 file changed, 42 insertions(+), 109 deletions(-) diff --git a/src/mam/mod_mam_rdbms_user.erl b/src/mam/mod_mam_rdbms_user.erl index 21a6f578c18..7733b2f9ab5 100644 --- a/src/mam/mod_mam_rdbms_user.erl +++ b/src/mam/mod_mam_rdbms_user.erl @@ -25,98 +25,31 @@ %% ---------------------------------------------------------------------- %% gen_mod callbacks -%% Starting and stopping functions for users' archives - --spec start(jid:server(), _) -> 'ok'. -start(Host, Opts) -> - 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(jid:server()) -> 'ok'. -stop(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. - -%% ---------------------------------------------------------------------- -%% Add hooks for mod_mam - --spec start_pm(jid:server(), _) -> 'ok'. -start_pm(Host, _Opts) -> +-spec start(mongooseim:host_type(), gen_mod:module_opts()) -> ok. +start(HostType, _Opts) -> prepare_queries(), - ejabberd_hooks:add(mam_archive_id, Host, ?MODULE, archive_id, 50), - case gen_mod:get_module_opt(Host, ?MODULE, auto_remove, false) of - true -> - ejabberd_hooks:add(mam_remove_archive, Host, ?MODULE, remove_archive, 90), - ok; - false -> - ok - end, + ejabberd_hooks:add(hooks(HostType)), ok. - --spec stop_pm(jid:server()) -> 'ok'. -stop_pm(Host) -> - ejabberd_hooks:delete(mam_archive_id, Host, ?MODULE, archive_id, 50), - case gen_mod:get_module_opt(Host, ?MODULE, auto_remove, false) of - true -> - ejabberd_hooks:delete(mam_remove_archive, Host, ?MODULE, remove_archive, 90), - ok; - false -> - ok - end, +-spec stop(mongooseim:host_type()) -> ok. +stop(HostType) -> + ejabberd_hooks:delete(hooks(HostType)), ok. +hooks(HostType) -> + [{Hook, HostType, ?MODULE, Fun, N} + || {true, Hook, Fun, N} <- hooks2(HostType)]. -%% ---------------------------------------------------------------------- -%% Add hooks for mod_mam_muc - --spec start_muc(jid:server(), _) -> 'ok'. -start_muc(Host, _Opts) -> - ejabberd_hooks:add(mam_muc_archive_id, Host, ?MODULE, archive_id, 50), - case gen_mod:get_module_opt(Host, ?MODULE, auto_remove, false) of - true -> - ejabberd_hooks:add(mam_muc_remove_archive, Host, ?MODULE, remove_archive, 90), - ok; - false -> - ok - end, - ok. - --spec stop_muc(jid:server()) -> 'ok'. -stop_muc(Host) -> - ejabberd_hooks:delete(mam_muc_archive_id, Host, ?MODULE, archive_id, 50), - case gen_mod:get_module_opt(Host, ?MODULE, auto_remove, false) of - true -> - ejabberd_hooks:delete(mam_muc_remove_archive, Host, ?MODULE, remove_archive, 90), - ok; - false -> - ok - end, - ok. +hooks2(HostType) -> + AR = gen_mod:get_module_opt(HostType, ?MODULE, auto_remove, false), + PM = gen_mod:get_module_opt(HostType, ?MODULE, pm, false), + MUC = gen_mod:get_module_opt(HostType, ?MODULE, muc, false), + [{PM, mam_archive_id, archive_id, 50}, + {PM and AR, mam_remove_archive, remove_archive, 90}, + {MUC, mam_muc_archive_id, archive_id, 50}, + {MUC and AR, mam_muc_remove_archive, remove_archive, 90}]. -%% Preparing queries prepare_queries() -> mongoose_rdbms:prepare(mam_user_insert, mam_server_user, [server, user_name], <<"INSERT INTO mam_server_user (server, user_name) VALUES (?, ?)">>), @@ -129,52 +62,52 @@ prepare_queries() -> %%==================================================================== %% API %%==================================================================== --spec archive_id(undefined | mod_mam:archive_id(), jid:server(), - jid:jid()) -> mod_mam:archive_id(). -archive_id(undefined, Host, _ArcJID=#jid{lserver = LServer, luser = LUser}) -> - query_archive_id(Host, LServer, LUser); +-spec archive_id(ArcID :: undefined | mod_mam:archive_id(), + HostType :: mongooseim:host_type(), + ArchiveJID :: jid:jid()) -> mod_mam:archive_id(). +archive_id(undefined, HostType, _ArcJID=#jid{lserver = LServer, luser = LUser}) -> + query_archive_id(HostType, LServer, LUser); archive_id(ArcID, _Host, _ArcJID) -> ArcID. --spec remove_archive(Acc :: map(), Host :: jid:server(), +-spec remove_archive(Acc :: map(), HostType :: mongooseim:host_type(), ArchiveID :: mod_mam:archive_id(), ArchiveJID :: jid:jid()) -> map(). -remove_archive(Acc, Host, ArcID, ArcJID) -> - remove_archive(Host, ArcID, ArcJID), +remove_archive(Acc, HostType, _ArcID, _ArcJID = #jid{lserver = LServer, luser = LUser}) -> + execute_user_remove(HostType, LServer, LUser), Acc. -remove_archive(Host, _ArcID, _ArcJID=#jid{lserver = LServer, luser = LUser}) -> - {updated, _} = - mongoose_rdbms:execute(Host, mam_user_remove, [LUser, LServer]). - - %%==================================================================== %% Internal functions %%==================================================================== --spec query_archive_id(jid:server(), jid:lserver(), jid:user()) -> integer(). -query_archive_id(Host, LServer, LUser) -> +execute_user_remove(HostType, LServer, LUser) -> + {updated, _} = + mongoose_rdbms:execute(HostType, mam_user_remove, [LUser, LServer]). + +-spec query_archive_id(mongooseim:host_type(), jid:lserver(), jid:luser()) -> integer(). +query_archive_id(HostType, LServer, LUser) -> Tries = 5, - query_archive_id(Host, LServer, LUser, Tries). + query_archive_id(HostType, LServer, LUser, Tries). -query_archive_id(Host, LServer, LUser, 0) -> +query_archive_id(HostType, LServer, LUser, 0) -> ?LOG_ERROR(#{what => query_archive_id_failed, - host => Host, server => LServer, user => LUser}), + host => HostType, server => LServer, user => LUser}), error(query_archive_id_failed); -query_archive_id(Host, LServer, LUser, Tries) when Tries > 0 -> - Result = mongoose_rdbms:execute(Host, mam_user_select, [LServer, LUser]), +query_archive_id(HostType, LServer, LUser, Tries) when Tries > 0 -> + Result = mongoose_rdbms:execute(HostType, mam_user_select, [LServer, LUser]), case Result of {selected, [{IdBin}]} -> mongoose_rdbms:result_to_integer(IdBin); {selected, []} -> %% The user is not found - create_user_archive(Host, LServer, LUser), - query_archive_id(Host, LServer, LUser, Tries - 1) + create_user_archive(HostType, LServer, LUser), + query_archive_id(HostType, LServer, LUser, Tries - 1) end. --spec create_user_archive(jid:server(), jid:lserver(), jid:user()) -> ok. -create_user_archive(Host, LServer, LUser) -> - Res = mongoose_rdbms:execute(Host, mam_user_insert, [LServer, LUser]), +-spec create_user_archive(mongooseim:host_type(), jid:lserver(), jid:luser()) -> ok. +create_user_archive(HostType, LServer, LUser) -> + Res = mongoose_rdbms:execute(HostType, mam_user_insert, [LServer, LUser]), case Res of {updated, 1} -> ok; @@ -186,6 +119,6 @@ create_user_archive(Host, LServer, LUser) -> %% - {error, "[FreeTDS][SQL Server]Violation of UNIQUE KEY constraint" ++ _} %% Let's ignore the errors and just retry in query_archive_id ?LOG_WARNING(#{what => create_user_archive_failed, reason => Res, - user => LUser, host => Host, server => LServer}), + user => LUser, host => HostType, server => LServer}), ok end. From d497d577a44f1d3d8c50ecabf9df6623c0dee56c Mon Sep 17 00:00:00 2001 From: Mikhail Uvarov Date: Wed, 16 Jun 2021 17:16:14 +0200 Subject: [PATCH 5/7] Refactor hook starting in mod_mam_rdbms_prefs Use HostType variable name in mod_mam_rdbms_prefs --- src/mam/mod_mam_rdbms_prefs.erl | 205 +++++++++++++------------------- 1 file changed, 82 insertions(+), 123 deletions(-) diff --git a/src/mam/mod_mam_rdbms_prefs.erl b/src/mam/mod_mam_rdbms_prefs.erl index 2173b94796c..b3fbeadc9dd 100644 --- a/src/mam/mod_mam_rdbms_prefs.erl +++ b/src/mam/mod_mam_rdbms_prefs.erl @@ -20,7 +20,8 @@ remove_archive/4]). -import(mongoose_rdbms, - [escape_string/1, + [prepare/4, + escape_string/1, escape_integer/1, use_escaped_string/1, use_escaped_integer/1]). @@ -34,127 +35,84 @@ %% gen_mod callbacks %% Starting and stopping functions for users' archives --spec start(jid:server(), _) -> 'ok'. -start(Host, Opts) -> - prepare_queries(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(jid:server()) -> 'ok'. -stop(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. - - -%% Prepared queries -prepare_queries(Host) -> - mongoose_rdbms:prepare(mam_prefs_insert, mam_config, [user_id, remote_jid, behaviour], - <<"INSERT INTO mam_config(user_id, remote_jid, behaviour) " - "VALUES (?, ?, ?)">>), - mongoose_rdbms:prepare(mam_prefs_select, mam_config, [user_id], - <<"SELECT remote_jid, behaviour " - "FROM mam_config WHERE user_id=?">>), - mongoose_rdbms:prepare(mam_prefs_select_behaviour, mam_config, - [user_id, remote_jid], - <<"SELECT remote_jid, behaviour " - "FROM mam_config " - "WHERE user_id=? " - "AND (remote_jid='' OR remote_jid=?)">>), - mongoose_rdbms:prepare(mam_prefs_select_behaviour2, mam_config, - [user_id, remote_jid, remote_jid], - <<"SELECT remote_jid, behaviour " - "FROM mam_config " - "WHERE user_id=? " - "AND (remote_jid='' OR remote_jid=? OR remote_jid=?)">>), - OrdBy = order_by_remote_jid_in_delete(Host), - mongoose_rdbms:prepare(mam_prefs_delete, mam_config, [user_id], - <<"DELETE FROM mam_config WHERE user_id=?", OrdBy/binary>>), +-spec start(mongooseim:host_type(), _) -> ok. +start(HostType, _Opts) -> + prepare_queries(HostType), + ejabberd_hooks:add(hooks(HostType)), ok. -order_by_remote_jid_in_delete(Host) -> - case mongoose_rdbms:db_engine(Host) of - mysql -> - <<" ORDER BY remote_jid">>; - _ -> - <<"">> - end. - - -%% ---------------------------------------------------------------------- -%% Add hooks for mod_mam - --spec start_pm(jid:server(), _) -> 'ok'. -start_pm(Host, _Opts) -> - ejabberd_hooks:add(mam_get_behaviour, Host, ?MODULE, get_behaviour, 50), - ejabberd_hooks:add(mam_get_prefs, Host, ?MODULE, get_prefs, 50), - ejabberd_hooks:add(mam_set_prefs, Host, ?MODULE, set_prefs, 50), - ejabberd_hooks:add(mam_remove_archive, Host, ?MODULE, remove_archive, 50), - ok. - - --spec stop_pm(jid:server()) -> 'ok'. -stop_pm(Host) -> - ejabberd_hooks:delete(mam_get_behaviour, Host, ?MODULE, get_behaviour, 50), - ejabberd_hooks:delete(mam_get_prefs, Host, ?MODULE, get_prefs, 50), - ejabberd_hooks:delete(mam_set_prefs, Host, ?MODULE, set_prefs, 50), - ejabberd_hooks:delete(mam_remove_archive, Host, ?MODULE, remove_archive, 50), +-spec stop(mongooseim:host_type()) -> ok. +stop(HostType) -> + ejabberd_hooks:delete(hooks(HostType)), ok. +hooks(HostType) -> + PM = gen_mod:get_module_opt(HostType, ?MODULE, pm, false), + MUC = gen_mod:get_module_opt(HostType, ?MODULE, muc, false), + case PM of + true -> pm_hooks(HostType); + false -> [] + end ++ + case MUC of + true -> muc_hooks(HostType); + false -> [] + end. -%% ---------------------------------------------------------------------- -%% Add hooks for mod_mam_muc_muc +pm_hooks(HostType) -> + [{mam_get_behaviour, HostType, ?MODULE, get_behaviour, 50}, + {mam_get_prefs, HostType, ?MODULE, get_prefs, 50}, + {mam_set_prefs, HostType, ?MODULE, set_prefs, 50}, + {mam_remove_archive, HostType, ?MODULE, remove_archive, 50}]. --spec start_muc(jid:server(), _) -> 'ok'. -start_muc(Host, _Opts) -> - ejabberd_hooks:add(mam_muc_get_behaviour, Host, ?MODULE, get_behaviour, 50), - ejabberd_hooks:add(mam_muc_get_prefs, Host, ?MODULE, get_prefs, 50), - ejabberd_hooks:add(mam_muc_set_prefs, Host, ?MODULE, set_prefs, 50), - ejabberd_hooks:add(mam_muc_remove_archive, Host, ?MODULE, remove_archive, 50), - ok. +muc_hooks(HostType) -> + [{mam_muc_get_behaviour, HostType, ?MODULE, get_behaviour, 50}, + {mam_muc_get_prefs, HostType, ?MODULE, get_prefs, 50}, + {mam_muc_set_prefs, HostType, ?MODULE, set_prefs, 50}, + {mam_muc_remove_archive, HostType, ?MODULE, remove_archive, 50}]. - --spec stop_muc(jid:server()) -> 'ok'. -stop_muc(Host) -> - ejabberd_hooks:delete(mam_muc_get_behaviour, Host, ?MODULE, get_behaviour, 50), - ejabberd_hooks:delete(mam_muc_get_prefs, Host, ?MODULE, get_prefs, 50), - ejabberd_hooks:delete(mam_muc_set_prefs, Host, ?MODULE, set_prefs, 50), - ejabberd_hooks:delete(mam_muc_remove_archive, Host, ?MODULE, remove_archive, 50), +%% Prepared queries +prepare_queries(HostType) -> + prepare(mam_prefs_insert, mam_config, [user_id, remote_jid, behaviour], + <<"INSERT INTO mam_config(user_id, remote_jid, behaviour) " + "VALUES (?, ?, ?)">>), + prepare(mam_prefs_select, mam_config, [user_id], + <<"SELECT remote_jid, behaviour " + "FROM mam_config WHERE user_id=?">>), + prepare(mam_prefs_select_behaviour, mam_config, + [user_id, remote_jid], + <<"SELECT remote_jid, behaviour " + "FROM mam_config " + "WHERE user_id=? " + "AND (remote_jid='' OR remote_jid=?)">>), + prepare(mam_prefs_select_behaviour2, mam_config, + [user_id, remote_jid, remote_jid], + <<"SELECT remote_jid, behaviour " + "FROM mam_config " + "WHERE user_id=? " + "AND (remote_jid='' OR remote_jid=? OR remote_jid=?)">>), + OrdBy = order_by_remote_jid_in_delete(HostType), + prepare(mam_prefs_delete, mam_config, [user_id], + <<"DELETE FROM mam_config WHERE user_id=?", OrdBy/binary>>), ok. +order_by_remote_jid_in_delete(HostType) -> + case mongoose_rdbms:db_engine(HostType) of + mysql -> <<" ORDER BY remote_jid">>; + _ -> <<>> + end. %% ---------------------------------------------------------------------- %% Internal functions and callbacks -spec get_behaviour(Default :: mod_mam:archive_behaviour(), - Host :: jid:server(), ArchiveID :: mod_mam:archive_id(), + HostType :: mongooseim:host_type(), ArchiveID :: mod_mam:archive_id(), LocJID :: jid:jid(), RemJID :: jid:jid()) -> any(). -get_behaviour(DefaultBehaviour, Host, UserID, _LocJID, RemJID) +get_behaviour(DefaultBehaviour, HostType, UserID, _LocJID, RemJID) when is_integer(UserID) -> RemLJID = jid:to_lower(RemJID), BRemLBareJID = jid:to_binary(jid:to_bare(RemLJID)), BRemLJID = jid:to_binary(RemLJID), - case query_behaviour(Host, UserID, BRemLJID, BRemLBareJID) of + case query_behaviour(HostType, UserID, BRemLJID, BRemLBareJID) of {selected, []} -> DefaultBehaviour; {selected, RemoteJid2Behaviour} -> @@ -178,57 +136,58 @@ choose_behaviour(BRemLJID, BRemLBareJID, RemoteJid2Behaviour) -> end end. --spec set_prefs(Result :: any(), Host :: jid:server(), +-spec set_prefs(Result :: any(), HostType :: mongooseim:host_type(), ArchiveID :: mod_mam:archive_id(), ArchiveJID :: jid:jid(), DefaultMode :: mod_mam:archive_behaviour(), AlwaysJIDs :: [jid:literal_jid()], NeverJIDs :: [jid:literal_jid()]) -> any(). -set_prefs(_Result, Host, UserID, _ArcJID, DefaultMode, AlwaysJIDs, NeverJIDs) -> +set_prefs(_Result, HostType, UserID, _ArcJID, DefaultMode, AlwaysJIDs, NeverJIDs) -> try - set_prefs1(Host, UserID, DefaultMode, AlwaysJIDs, NeverJIDs) + set_prefs1(HostType, UserID, DefaultMode, AlwaysJIDs, NeverJIDs) catch _Type:Error -> {error, Error} end. -set_prefs1(Host, UserID, DefaultMode, AlwaysJIDs, NeverJIDs) -> +set_prefs1(HostType, UserID, DefaultMode, AlwaysJIDs, NeverJIDs) -> Rows = prefs_to_rows(UserID, DefaultMode, AlwaysJIDs, NeverJIDs), %% MySQL sometimes aborts transaction with reason: %% "Deadlock found when trying to get lock; try restarting transaction" - mongoose_rdbms:transaction_with_delayed_retry(Host, fun() -> + mongoose_rdbms:transaction_with_delayed_retry(HostType, fun() -> {updated, _} = - mongoose_rdbms:execute(Host, mam_prefs_delete, [UserID]), - [mongoose_rdbms:execute(Host, mam_prefs_insert, Row) || Row <- Rows], + mongoose_rdbms:execute(HostType, mam_prefs_delete, [UserID]), + [mongoose_rdbms:execute(HostType, mam_prefs_insert, Row) || Row <- Rows], ok end, #{user_id => UserID, retries => 5, delay => 100}), ok. --spec get_prefs(mod_mam:preference(), _Host :: jid:server(), +-spec get_prefs(mod_mam:preference(), HostType :: mongooseim:host_type(), ArchiveID :: mod_mam:archive_id(), ArchiveJID :: jid:jid()) -> mod_mam:preference(). -get_prefs({GlobalDefaultMode, _, _}, Host, UserID, _ArcJID) -> - {selected, Rows} = mongoose_rdbms:execute(Host, mam_prefs_select, [UserID]), +get_prefs({GlobalDefaultMode, _, _}, HostType, UserID, _ArcJID) -> + {selected, Rows} = mongoose_rdbms:execute(HostType, mam_prefs_select, [UserID]), decode_prefs_rows(Rows, GlobalDefaultMode, [], []). --spec remove_archive(mongoose_acc:t(), jid:server(), mod_mam:archive_id(), jid:jid()) -> +-spec remove_archive(mongoose_acc:t(), mongooseim:host_type(), + mod_mam:archive_id(), jid:jid()) -> mongoose_acc:t(). -remove_archive(Acc, Host, UserID, _ArcJID) -> - remove_archive(Host, UserID), +remove_archive(Acc, HostType, UserID, _ArcJID) -> + remove_archive(HostType, UserID), Acc. -remove_archive(Host, UserID) -> +remove_archive(HostType, UserID) -> {updated, _} = - mongoose_rdbms:execute(Host, mam_prefs_delete, [UserID]). + mongoose_rdbms:execute(HostType, mam_prefs_delete, [UserID]). --spec query_behaviour(jid:server(), +-spec query_behaviour(HostType :: mongooseim:host_type(), UserID :: non_neg_integer(), BRemLJID :: binary(), BRemLBareJID :: binary() ) -> any(). -query_behaviour(Host, UserID, BRemLJID, BRemLJID) -> - mongoose_rdbms:execute(Host, mam_prefs_select_behaviour, +query_behaviour(HostType, UserID, BRemLJID, BRemLJID) -> + mongoose_rdbms:execute(HostType, mam_prefs_select_behaviour, [UserID, BRemLJID]); %% check just bare jid -query_behaviour(Host, UserID, BRemLJID, BRemLBareJID) -> - mongoose_rdbms:execute(Host, mam_prefs_select_behaviour2, +query_behaviour(HostType, UserID, BRemLJID, BRemLBareJID) -> + mongoose_rdbms:execute(HostType, mam_prefs_select_behaviour2, [UserID, BRemLJID, BRemLBareJID]). %% ---------------------------------------------------------------------- From ea1cec1345cea2230b65ecc0766bcffd54554393 Mon Sep 17 00:00:00 2001 From: Mikhail Uvarov Date: Wed, 16 Jun 2021 17:44:57 +0200 Subject: [PATCH 6/7] Use host_types in mod_mam_cache_user --- src/mam/mod_mam_cache_user.erl | 195 +++++++++------------------------ 1 file changed, 51 insertions(+), 144 deletions(-) diff --git a/src/mam/mod_mam_cache_user.erl b/src/mam/mod_mam_cache_user.erl index 770776553a2..9aff0e7b99f 100644 --- a/src/mam/mod_mam_cache_user.erl +++ b/src/mam/mod_mam_cache_user.erl @@ -39,7 +39,6 @@ -record(state, {}). -%% @private srv_name() -> mod_mam_cache. @@ -49,113 +48,70 @@ 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) -> - 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 start(HostType :: mongooseim:host_type(), Opts :: gen_mod:module_opts()) -> ok. +start(HostType, _Opts) -> + start_server(), + ejabberd_hooks:add(hooks(HostType)), ok. - --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), +-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]}. -%% ---------------------------------------------------------------------- -%% Add hooks for mod_mam_muc +start_server() -> + %% TODO make per host server + supervisor:start_child(ejabberd_sup, writer_child_spec()). --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. +hooks(HostType) -> + PM = gen_mod:get_module_opt(HostType, ?MODULE, pm, false), + MUC = gen_mod:get_module_opt(HostType, ?MODULE, muc, false), + case PM of + true -> + pm_hooks(HostType); + false -> + [] + end ++ + case MUC of + true -> + muc_hooks(HostType); + false -> + [] + end. +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}]. --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. - +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), @@ -164,19 +120,15 @@ 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. @@ -184,24 +136,22 @@ remove_archive(Acc, _Host, _UserID, ArcJID) -> %% 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) @@ -209,8 +159,7 @@ lookup_archive_id(ArcJID) -> 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 @@ -225,13 +174,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()), @@ -241,27 +183,10 @@ 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}; @@ -269,31 +194,13 @@ 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}. From 5ff96d7d458218de155f8765312bea95cd6fd5c1 Mon Sep 17 00:00:00 2001 From: Mikhail Uvarov Date: Thu, 17 Jun 2021 13:57:06 +0200 Subject: [PATCH 7/7] Add maybe_pm_hooks function for cache_user/rdbms_prefs --- src/mam/mod_mam_cache_user.erl | 19 +++++++------------ src/mam/mod_mam_rdbms_prefs.erl | 15 +++++++-------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/mam/mod_mam_cache_user.erl b/src/mam/mod_mam_cache_user.erl index 9aff0e7b99f..a6613449c69 100644 --- a/src/mam/mod_mam_cache_user.erl +++ b/src/mam/mod_mam_cache_user.erl @@ -78,18 +78,13 @@ start_server() -> hooks(HostType) -> PM = gen_mod:get_module_opt(HostType, ?MODULE, pm, false), MUC = gen_mod:get_module_opt(HostType, ?MODULE, muc, false), - case PM of - true -> - pm_hooks(HostType); - false -> - [] - end ++ - case MUC of - true -> - muc_hooks(HostType); - false -> - [] - end. + maybe_pm_hooks(PM, HostType) ++ maybe_muc_hooks(MUC, HostType). + +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) -> []. pm_hooks(HostType) -> [{mam_archive_id, HostType, ?MODULE, cached_archive_id, 30}, diff --git a/src/mam/mod_mam_rdbms_prefs.erl b/src/mam/mod_mam_rdbms_prefs.erl index b3fbeadc9dd..420a990ff21 100644 --- a/src/mam/mod_mam_rdbms_prefs.erl +++ b/src/mam/mod_mam_rdbms_prefs.erl @@ -49,14 +49,13 @@ stop(HostType) -> hooks(HostType) -> PM = gen_mod:get_module_opt(HostType, ?MODULE, pm, false), MUC = gen_mod:get_module_opt(HostType, ?MODULE, muc, false), - case PM of - true -> pm_hooks(HostType); - false -> [] - end ++ - case MUC of - true -> muc_hooks(HostType); - false -> [] - end. + maybe_pm_hooks(PM, HostType) ++ maybe_muc_hooks(MUC, HostType). + +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) -> []. pm_hooks(HostType) -> [{mam_get_behaviour, HostType, ?MODULE, get_behaviour, 50},