77]).
88
99-define (ETS , hpr_netid_stats_ets ).
10+ -define (CLEANER , hpr_netid_stats_cleaner ).
11+ -define (HOUR_MS , timer :hours (1 )).
1012
1113-spec init () -> ok .
1214init () ->
@@ -16,6 +18,7 @@ init() ->
1618 set ,
1719 {write_concurrency , true }
1820 ]),
21+ ok = ensure_cleaner (),
1922 ok .
2023
2124-spec maybe_report_net_id (PacketUp :: hpr_packet_up :packet ()) -> ok .
@@ -25,7 +28,7 @@ maybe_report_net_id(PacketUp) ->
2528 ok ;
2629 {ok , NetId } ->
2730 ets :update_counter (
28- ? ETS , NetId , {2 , 1 }, {default , 0 }
31+ ? ETS , NetId , {2 , 1 }, {default , 0 , erlang : system_time ( millisecond ) }
2932 ),
3033 ok
3134 end .
@@ -34,6 +37,39 @@ maybe_report_net_id(PacketUp) ->
3437export () ->
3538 ets :tab2list (? ETS ).
3639
40+ % % ------------------------------------------------------------------
41+ % % Internal Function Definitions
42+ % % ------------------------------------------------------------------
43+
44+ ensure_cleaner () ->
45+ case erlang :whereis (? CLEANER ) of
46+ undefined ->
47+ Pid = erlang :spawn (fun cleaner_loop /0 ),
48+ true = erlang :register (? CLEANER , Pid ),
49+ ok ;
50+ _Pid ->
51+ ok
52+ end .
53+
54+ cleaner_loop () ->
55+ catch cleanup_old (),
56+ receive
57+ stop -> ok
58+ after ? HOUR_MS ->
59+ cleaner_loop ()
60+ end .
61+
62+ -spec cleanup_old () -> ok .
63+ cleanup_old () ->
64+ Now = erlang :system_time (millisecond ),
65+ OneDayAgo = Now - timer :hours (24 ),
66+ % % Match-spec: match any {_, _, TS} where TS < OneDayAgo, delete it.
67+ MS = [
68+ {{'_' , '_' , '$1' }, [{'<' , '$1' , OneDayAgo }], [true ]}
69+ ],
70+ DeletedCount = ets :select_delete (? ETS , MS ),
71+ lager :debug (" removed ~p entries older than 24h" , [DeletedCount ]).
72+
3773% % ------------------------------------------------------------------
3874% % EUNIT Tests
3975% % ------------------------------------------------------------------
@@ -43,15 +79,18 @@ export() ->
4379
4480all_test_ () ->
4581 {foreach , fun foreach_setup /0 , fun foreach_cleanup /1 , [
46- ? _test (test_maybe_report_net_id ())
82+ ? _test (test_maybe_report_net_id ()),
83+ ? _test (test_cleanup_old ())
4784 ]}.
4885
4986foreach_setup () ->
87+ application :ensure_all_started (lager ),
5088 ok = ? MODULE :init (),
5189 ok .
5290
5391foreach_cleanup (ok ) ->
5492 _ = catch ets :delete (? ETS ),
93+ application :stop (lager ),
5594 ok .
5695
5796test_maybe_report_net_id () ->
@@ -61,8 +100,16 @@ test_maybe_report_net_id() ->
61100 ? assertEqual (ok , maybe_report_net_id (PacketUp )),
62101 ? assertEqual (ok , maybe_report_net_id (PacketUp )),
63102
64- ? assertEqual ([{0 , 3 }], ets :tab2list (? ETS )),
103+ ? assertMatch ([{0 , 3 , _ }], ets :tab2list (? ETS )),
65104
66105 ok .
67106
107+ test_cleanup_old () ->
108+ % % seed: one fresh, one old
109+ T0 = erlang :system_time (millisecond ),
110+ ets :insert (? ETS , {1 , 3 , T0 }),
111+ ets :insert (? ETS , {2 , 5 , T0 - 25 * 60 * 60 * 1000 }),
112+ ok = cleanup_old (),
113+ ? assertEqual ([{1 , 3 , T0 }], lists :sort (ets :tab2list (? ETS ))).
114+
68115-endif .
0 commit comments