./ct_report/coverage/stream_management_stale_h.COVER.html

1 -module(stream_management_stale_h).
2 -behaviour(gen_server).
3
4 -include("mongoose.hrl").
5 -include_lib("stdlib/include/ms_transform.hrl").
6
7 -record(smgc_state,
8 {gc_repeat_after :: non_neg_integer(),
9 gc_geriatric :: non_neg_integer()
10 }).
11
12 -record(stream_mgmt_stale_h,
13 {smid :: mod_stream_management:smid(),
14 h :: non_neg_integer(),
15 stamp :: non_neg_integer()
16 }).
17
18 -export([read_stale_h/1,
19 write_stale_h/2,
20 delete_stale_h/1,
21 clear_table/1
22 ]).
23
24 -export([maybe_start/1]).
25
26 %% Internal exports
27 -export([start_link/1]).
28 %% gen_server callbacks
29 -export([init/1,
30 handle_call/3,
31 handle_cast/2,
32 handle_info/2
33 ]).
34
35 -ignore_xref([clear_table/1, start_link/1]).
36
37 -spec read_stale_h(SMID :: mod_stream_management:smid()) ->
38 {stale_h, non_neg_integer()} | {error, smid_not_found}.
39 read_stale_h(SMID) ->
40 37 try
41 37 case mnesia:dirty_read(stream_mgmt_stale_h, SMID) of
42 36 [#stream_mgmt_stale_h{h = H}] -> {stale_h, H};
43 1 [] -> {error, smid_not_found}
44 end
45 catch exit:_Reason ->
46
:-(
{error, smid_not_found}
47 end.
48
49 -spec write_stale_h(SMID :: mod_stream_management:smid(), H :: non_neg_integer()) ->
50 ok | {error, any()}.
51 write_stale_h(SMID, H) ->
52 8 try
53 8 Stamp = erlang:monotonic_time(second),
54 8 mnesia:dirty_write(#stream_mgmt_stale_h{smid = SMID, h = H, stamp = Stamp})
55 catch exit:Reason ->
56
:-(
{error, Reason}
57 end.
58
59 -spec delete_stale_h(SMID :: mod_stream_management:smid()) ->
60 ok | {error, any()}.
61 delete_stale_h(SMID) ->
62
:-(
try
63
:-(
mnesia:dirty_delete(stream_mgmt_stale_h, SMID)
64 catch exit:Reason ->
65
:-(
{error, Reason}
66 end.
67
68
69 %%
70 %% gen_server
71 maybe_start(Opts) ->
72 375 StaleOpts = gen_mod:get_opt(stale_h, Opts, [{enabled, false}]),
73 375 case proplists:get_value(enabled, StaleOpts, false) of
74 false ->
75 372 ok;
76 true ->
77 3 ?LOG_INFO(#{what => stream_mgmt_stale_h_start}),
78 3 mnesia:create_table(stream_mgmt_stale_h,
79 [{ram_copies, [node()]},
80 {attributes, record_info(fields, stream_mgmt_stale_h)}]),
81 3 mnesia:add_table_copy(stream_mgmt_stale_h, node(), ram_copies),
82 3 start_cleaner(StaleOpts)
83 end.
84
85 start_cleaner(Opts) ->
86 3 ChildSpec = {?MODULE,
87 {?MODULE, start_link, [Opts]},
88 permanent, 5000, worker, [?MODULE]},
89 3 ejabberd_sup:start_child(ChildSpec).
90
91 start_link(Opts) ->
92 3 gen_server:start_link({local, ?MODULE}, ?MODULE, [Opts], []).
93
94 init([GCOpts]) ->
95 3 RepeatAfter = proplists:get_value(stale_h_repeat_after, GCOpts, 1800),
96 3 GeriatricAge = proplists:get_value(stale_h_geriatric, GCOpts, 3600),
97 3 State = #smgc_state{gc_repeat_after = RepeatAfter,
98 gc_geriatric = GeriatricAge},
99 3 {ok, State, RepeatAfter}.
100
101 handle_call(Msg, From, State) ->
102
:-(
?UNEXPECTED_CALL(Msg, From),
103
:-(
{reply, ok, State}.
104
105 handle_cast(Msg, State) ->
106
:-(
?UNEXPECTED_CAST(Msg),
107
:-(
{noreply, State}.
108
109 handle_info(timeout, #smgc_state{gc_repeat_after = RepeatAfter,
110 gc_geriatric = GeriatricAge} = State) ->
111 808 clear_table(GeriatricAge),
112 808 {noreply, State, RepeatAfter};
113 handle_info(Info, #smgc_state{gc_repeat_after = RepeatAfter,
114 gc_geriatric = _GeriatricAge} = State) ->
115
:-(
?UNEXPECTED_INFO(Info),
116
:-(
{noreply, State, RepeatAfter}.
117
118 clear_table(GeriatricAge) ->
119 808 TimeToDie = erlang:monotonic_time(second) - GeriatricAge,
120 808 MS = ets:fun2ms(fun(#stream_mgmt_stale_h{stamp=S}) when S < TimeToDie -> true end),
121 808 ets:select_delete(stream_mgmt_stale_h, MS).
Line Hits Source