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