./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, request_delete_domain/2]).
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 %% ---------------------------------------------------------------------------
20 %% Client code
21
22 -spec start(mongoose_service:options()) -> ok.
23 start(Opts) ->
24 345 ChildSpec =
25 {?MODULE,
26 {?MODULE, start_link, [Opts]},
27 permanent, infinity, worker, [?MODULE]},
28 345 supervisor:start_child(ejabberd_sup, ChildSpec),
29 345 ok.
30
31 -spec stop() -> ok.
32 stop() ->
33 342 supervisor:terminate_child(ejabberd_sup, ?MODULE),
34 342 supervisor:delete_child(ejabberd_sup, ?MODULE),
35 342 ok.
36
37 start_link(Opts) ->
38 345 gen_server:start_link({local, ?MODULE}, ?MODULE, Opts, []).
39
40 -spec request_delete_domain(jid:lserver(), mongooseim:host_type()) -> ok.
41 request_delete_domain(Domain, HostType) ->
42 5 gen_server:cast(?MODULE, {delete_domain, Domain, HostType}).
43
44 %% ---------------------------------------------------------------------------
45 %% Server callbacks
46
47 init(#{event_cleaning_interval := Interval, event_max_age := MaxAge}) ->
48 345 ?LOG_INFO(#{what => domain_cleaner_start, cleaning_interval => Interval, max_age => MaxAge}),
49 345 State = #{max_age => MaxAge},
50 345 self() ! schedule_removal,
51 345 timer:send_interval(timer:seconds(Interval), schedule_removal),
52 345 {ok, State}.
53
54 handle_call(Request, From, State) ->
55
:-(
?UNEXPECTED_CALL(Request, From),
56
:-(
{reply, ok, State}.
57
58 handle_cast({delete_domain, Domain, HostType}, State) ->
59 5 {noreply, handle_delete_domain(Domain, HostType, State)};
60 handle_cast(Msg, State) ->
61
:-(
?UNEXPECTED_CAST(Msg),
62
:-(
{noreply, State}.
63
64 handle_info(schedule_removal, State) ->
65 349 {noreply, schedule_removal(State)};
66 handle_info({timeout, TimerRef, Msg}, State) ->
67 2 {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 349 try mongoose_domain_sql:get_minmax_event_id() of
85 {_Min, LastEventId} ->
86 349 Msg = {do_removal, LastEventId},
87 349 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 349 State.
95
96 handle_timeout(_TimerRef, {do_removal, LastEventId}, State) ->
97 2 mongoose_domain_sql:delete_events_older_than(LastEventId),
98 2 State.
99
100 handle_delete_domain(Domain, HostType, State) ->
101 5 try
102 5 mongoose_domain_api:do_delete_domain_in_progress(Domain, HostType)
103 catch Class:Reason:Stacktrace ->
104
:-(
?LOG_ERROR(#{what => domain_deletion_failed,
105 domain => Domain, host_type => HostType,
106
:-(
class => Class, reason => Reason, stacktrace => Stacktrace})
107 end,
108 5 State.
Line Hits Source