./ct_report/coverage/mongoose_domain_db_cleaner.COVER.html

1 %% Cleaning is triggered from all MongooseIM nodes.
2 %% Though, it's quick, if there is nothing to remove.
3 -module(mongoose_domain_db_cleaner).
4 -include("mongoose_logger.hrl").
5
6 -export([start/1, stop/0]).
7 -export([start_link/1]).
8
9 %% gen_server callbacks
10 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
11 terminate/2, code_change/3]).
12
13 -ignore_xref([code_change/3, handle_call/3, handle_cast/2, handle_info/2, init/1,
14 start_link/1, terminate/2]).
15
16 %% ---------------------------------------------------------------------------
17 %% Config
18
19 default_cleaning_interval() ->
20
:-(
1800. %% 30 minutes
21
22 default_max_age() ->
23
:-(
7200. %% 2 hours
24
25 %% ---------------------------------------------------------------------------
26 %% Client code
27
28 start(Opts) ->
29
:-(
ChildSpec =
30 {?MODULE,
31 {?MODULE, start_link, [Opts]},
32 permanent, infinity, worker, [?MODULE]},
33
:-(
supervisor:start_child(ejabberd_sup, ChildSpec),
34
:-(
ok.
35
36 stop() ->
37
:-(
supervisor:terminate_child(ejabberd_sup, ?MODULE),
38
:-(
supervisor:delete_child(ejabberd_sup, ?MODULE),
39
:-(
ok.
40
41 start_link(Opts) ->
42
:-(
gen_server:start_link({local, ?MODULE}, ?MODULE, Opts, []).
43
44 %% ---------------------------------------------------------------------------
45 %% Server callbacks
46
47 init(Opts) ->
48
:-(
Interval = proplists:get_value(event_cleaning_interval, Opts, default_cleaning_interval()),
49
:-(
MaxAge = proplists:get_value(event_max_age, Opts, default_max_age()),
50
:-(
?LOG_INFO(#{what => domain_cleaner_start, cleaning_interval => Interval, max_age => MaxAge}),
51
:-(
State = #{max_age => MaxAge},
52
:-(
self() ! schedule_removal,
53
:-(
timer:send_interval(timer:seconds(Interval), schedule_removal),
54
:-(
{ok, State}.
55
56 handle_call(Request, From, State) ->
57
:-(
?UNEXPECTED_CALL(Request, From),
58
:-(
{reply, ok, State}.
59
60 handle_cast(Msg, State) ->
61
:-(
?UNEXPECTED_CAST(Msg),
62
:-(
{noreply, State}.
63
64 handle_info(schedule_removal, State) ->
65
:-(
{noreply, schedule_removal(State)};
66 handle_info({timeout, TimerRef, Msg}, State) ->
67
:-(
{noreply, handle_timeout(TimerRef, Msg, State)};
68 handle_info(Info, State) ->
69
:-(
?UNEXPECTED_INFO(Info),
70
:-(
{noreply, State}.
71
72 terminate(_Reason, _State) ->
73
:-(
ok.
74
75 code_change(_OldVsn, State, _Extra) ->
76
:-(
{ok, State}.
77
78 %% ---------------------------------------------------------------------------
79 %% Server helpers
80
81 %% We are ensuring that to remove events, they have to be in the database
82 %% for some amount of time
83 schedule_removal(State = #{max_age := MaxAge}) ->
84
:-(
try mongoose_domain_sql:get_minmax_event_id() of
85 {_Min, LastEventId} ->
86
:-(
Msg = {do_removal, LastEventId},
87
:-(
erlang:start_timer(timer:seconds(MaxAge), self(), Msg)
88 catch Class:Reason:Stacktrace ->
89 %% It's safe to skip scheduling
90
:-(
?LOG_ERROR(#{what => domain_cleaning_schedule_failed,
91 text => <<"Failed to get LastEventId">>,
92
:-(
class => Class, reason => Reason, stacktrace => Stacktrace})
93 end,
94
:-(
State.
95
96 handle_timeout(_TimerRef, {do_removal, LastEventId}, State) ->
97
:-(
mongoose_domain_sql:delete_events_older_than(LastEventId),
98
:-(
State.
Line Hits Source