1 |
|
-module(mod_muc_light_cache). |
2 |
|
|
3 |
|
-include("mongoose_config_spec.hrl"). |
4 |
|
|
5 |
|
-behaviour(gen_mod). |
6 |
|
-define(FRONTEND, mod_muc_light). |
7 |
|
|
8 |
|
%% gen_mod callbacks |
9 |
|
-export([start/2, stop/1, config_spec/0, supported_features/0]). |
10 |
|
|
11 |
|
%% Hook handlers |
12 |
|
-export([pre_acc_room_affiliations/2, post_acc_room_affiliations/2, |
13 |
|
pre_room_exists/3, post_room_exists/3, |
14 |
|
forget_room/4, remove_domain/3, room_new_affiliations/4]). |
15 |
|
-ignore_xref([pre_acc_room_affiliations/2, post_acc_room_affiliations/2, |
16 |
|
pre_room_exists/3, post_room_exists/3, |
17 |
|
forget_room/4, remove_domain/3, room_new_affiliations/4]). |
18 |
|
|
19 |
|
%% For tests |
20 |
|
-export([force_clear/1]). |
21 |
|
|
22 |
|
-spec start(mongooseim:host_type(), gen_mod:module_opts()) -> ok. |
23 |
|
start(HostType, Opts) -> |
24 |
1 |
start_cache(HostType, Opts), |
25 |
1 |
ejabberd_hooks:add(hooks(HostType)), |
26 |
1 |
ok. |
27 |
|
|
28 |
|
-spec stop(mongooseim:host_type()) -> ok. |
29 |
|
stop(HostType) -> |
30 |
1 |
ejabberd_hooks:delete(hooks(HostType)), |
31 |
1 |
stop_cache(HostType), |
32 |
1 |
ok. |
33 |
|
|
34 |
|
-spec config_spec() -> mongoose_config_spec:config_section(). |
35 |
|
config_spec() -> |
36 |
164 |
Section = #section{defaults = Defaults} = mongoose_user_cache:config_spec(), |
37 |
164 |
Section#section{defaults = Defaults#{<<"time_to_live">> := 2}}. |
38 |
|
|
39 |
|
-spec supported_features() -> [atom()]. |
40 |
|
supported_features() -> |
41 |
:-( |
[dynamic_domains]. |
42 |
|
|
43 |
|
-spec hooks(mongooseim:host_type()) -> [ejabberd_hooks:hook()]. |
44 |
|
hooks(HostType) -> |
45 |
2 |
[ |
46 |
|
{acc_room_affiliations, HostType, ?MODULE, pre_acc_room_affiliations, 40}, |
47 |
|
{acc_room_affiliations, HostType, ?MODULE, post_acc_room_affiliations, 60}, |
48 |
|
{room_exists, HostType, ?MODULE, pre_room_exists, 40}, |
49 |
|
{room_exists, HostType, ?MODULE, post_room_exists, 60}, |
50 |
|
{forget_room, HostType, ?MODULE, forget_room, 80}, |
51 |
|
{remove_domain, HostType, ?MODULE, remove_domain, 20}, |
52 |
|
{room_new_affiliations, HostType, ?MODULE, room_new_affiliations, 50} |
53 |
|
]. |
54 |
|
|
55 |
|
-spec pre_acc_room_affiliations(mongoose_acc:t(), jid:jid()) -> |
56 |
|
mongoose_acc:t() | {stop, mongoose_acc:t()}. |
57 |
|
pre_acc_room_affiliations(Acc, RoomJid) -> |
58 |
55 |
case mongoose_acc:get(?FRONTEND, affiliations, {error, not_exists}, Acc) of |
59 |
|
{error, _} -> |
60 |
55 |
HostType = mongoose_acc:host_type(Acc), |
61 |
55 |
case mongoose_user_cache:get_entry(HostType, ?MODULE, RoomJid) of |
62 |
|
#{affs := Res} -> |
63 |
28 |
mongoose_acc:set(?FRONTEND, affiliations, Res, Acc); |
64 |
|
_ -> |
65 |
27 |
Acc |
66 |
|
end; |
67 |
|
_Res -> |
68 |
:-( |
{stop, Acc} |
69 |
|
end. |
70 |
|
|
71 |
|
-spec post_acc_room_affiliations(mongoose_acc:t(), jid:jid()) -> mongoose_acc:t(). |
72 |
|
post_acc_room_affiliations(Acc, RoomJid) -> |
73 |
55 |
case mongoose_acc:get(?FRONTEND, affiliations, {error, not_exists}, Acc) of |
74 |
|
{error, _} -> |
75 |
:-( |
Acc; |
76 |
|
Res -> |
77 |
55 |
HostType = mongoose_acc:host_type(Acc), |
78 |
55 |
mongoose_user_cache:merge_entry(HostType, ?MODULE, RoomJid, #{affs => Res}), |
79 |
55 |
Acc |
80 |
|
end. |
81 |
|
|
82 |
|
-spec pre_room_exists(boolean(), mongooseim:host_type(), jid:jid()) -> |
83 |
|
boolean() | {stop, true}. |
84 |
|
pre_room_exists(false, HostType, RoomJid) -> |
85 |
56 |
case mongoose_user_cache:is_member(HostType, ?MODULE, RoomJid) of |
86 |
28 |
true -> {stop, true}; |
87 |
28 |
false -> false |
88 |
|
end; |
89 |
|
pre_room_exists(Status, _, _) -> |
90 |
:-( |
Status. |
91 |
|
|
92 |
|
-spec post_room_exists(boolean(), mongooseim:host_type(), jid:jid()) -> |
93 |
|
boolean(). |
94 |
|
post_room_exists(true, HostType, RoomJid) -> |
95 |
27 |
mongoose_user_cache:merge_entry(HostType, ?MODULE, RoomJid, #{}), |
96 |
27 |
true; |
97 |
|
post_room_exists(Status, _, _) -> |
98 |
1 |
Status. |
99 |
|
|
100 |
|
-spec forget_room(mongoose_hooks:simple_acc(), mongooseim:host_type(), jid:lserver(), binary()) -> |
101 |
|
mongoose_hooks:simple_acc(). |
102 |
|
forget_room(Acc, HostType, RoomS, RoomU) -> |
103 |
56 |
mongoose_user_cache:delete_user(HostType, ?MODULE, jid:make_noprep(RoomU, RoomS, <<>>)), |
104 |
56 |
Acc. |
105 |
|
|
106 |
|
-spec remove_domain(mongoose_hooks:simple_acc(), mongooseim:host_type(), jid:lserver()) -> |
107 |
|
mongoose_hooks:simple_acc(). |
108 |
|
remove_domain(Acc, HostType, Domain) -> |
109 |
:-( |
MUCHost = mod_muc_light:server_host_to_muc_host(HostType, Domain), |
110 |
:-( |
mongoose_user_cache:delete_domain(HostType, ?MODULE, MUCHost), |
111 |
:-( |
Acc. |
112 |
|
|
113 |
|
-spec room_new_affiliations(mongoose_acc:t(), jid:jid(), mod_muc_light:aff_users(), binary()) -> |
114 |
|
mongoose_acc:t(). |
115 |
|
room_new_affiliations(Acc, RoomJid, NewAffs, NewVersion) -> |
116 |
10 |
HostType = mod_muc_light_utils:acc_to_host_type(Acc), |
117 |
|
% make sure other nodes forget about stale values |
118 |
10 |
mongoose_user_cache:delete_user(HostType, ?MODULE, RoomJid), |
119 |
10 |
mongoose_user_cache:merge_entry(HostType, ?MODULE, RoomJid, #{affs => {ok, NewAffs, NewVersion}}), |
120 |
10 |
Acc. |
121 |
|
|
122 |
|
-spec force_clear(mongooseim:host_type()) -> ok. |
123 |
|
force_clear(HostType) -> |
124 |
81 |
CacheName = gen_mod:get_module_proc(HostType, ?MODULE), |
125 |
81 |
segmented_cache:delete_pattern(CacheName, {'_', '_'}), |
126 |
48 |
ok. |
127 |
|
|
128 |
|
%%==================================================================== |
129 |
|
%% internal |
130 |
|
%%==================================================================== |
131 |
|
-spec start_cache(mongooseim:host_type(), gen_mod:module_opts()) -> any(). |
132 |
|
start_cache(HostType, Opts) -> |
133 |
1 |
mongoose_user_cache:start_new_cache(HostType, ?MODULE, Opts). |
134 |
|
|
135 |
|
-spec stop_cache(mongooseim:host_type()) -> any(). |
136 |
|
stop_cache(HostType) -> |
137 |
1 |
mongoose_user_cache:stop_cache(HostType, ?MODULE). |