fix scanner

This commit is contained in:
anlicheng 2025-12-16 22:25:20 +08:00
parent 16df064dab
commit 4bd53d0afb
3 changed files with 100 additions and 0 deletions

View File

@ -8,6 +8,9 @@
%%%-------------------------------------------------------------------
-author("anlicheng").
-define(PENDING_TAB, ets_dns_pending_queries).
-define(PENDING_INDEX_TAB, ets_dns_expire_index).
-record(dns_cache, {
%% {Qname, QType, QClass}
key,

View File

@ -0,0 +1,46 @@
%%%-------------------------------------------------------------------
%%% @author anlicheng
%%% @copyright (C) 2025, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 16. 12 2025 14:38
%%%-------------------------------------------------------------------
-module(dns_pending_queries).
-author("anlicheng").
-include("dns_proxy.hrl").
%% API
-export([new/0, put/3, take/1, delete/1]).
-spec new() -> no_return().
new() ->
ets:new(?PENDING_TAB, [set, public, {read_concurrency, true}, {write_concurrency, true}]),
ets:new(?PENDING_INDEX_TAB, [bag, public, {read_concurrency, true}, {write_concurrency, true}]).
-spec put(Key :: any(), Value :: any(), TTL :: integer()) -> no_return().
put(Key, Value, TTL) when is_integer(TTL) ->
ExpireAt = erlang:monotonic_time(millisecond) + TTL,
ets:insert(?PENDING_TAB, {Key, {Value, ExpireAt}}),
ets:insert(?PENDING_INDEX_TAB, {ExpireAt, Key}).
-spec take(Key :: any()) -> error | {ok, Value :: any()}.
take(Key) ->
case ets:lookup(?PENDING_TAB, Key) of
[{Key, {Value, ExpireAt}}] ->
ets:delete(?PENDING_TAB, Key),
ets:delete(?PENDING_INDEX_TAB, ExpireAt),
{ok, Value};
[] ->
error
end.
-spec delete(Key :: any()) -> no_return().
delete(Key) ->
case ets:lookup(?PENDING_TAB, Key) of
[{Key, {_Value, ExpireAt}}] ->
ets:delete(?PENDING_TAB, Key),
ets:delete(?PENDING_INDEX_TAB, ExpireAt);
[] ->
ok
end.

View File

@ -0,0 +1,51 @@
%%%-------------------------------------------------------------------
%%% @author anlicheng
%%% @copyright (C) 2025, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 16. 12 2025 14:46
%%%-------------------------------------------------------------------
-module(dns_pending_scanner).
-author("anlicheng").
-include("dns_proxy.hrl").
%%
-define(MAX_NUM, 500).
-record(state, {
}).
%% API
-export([start_link/0, init/0]).
start_link() ->
{ok, spawn_link(?MODULE, init, [])}.
init() ->
cleaner_loop(#state{}).
cleaner_loop(State) ->
Now = erlang:monotonic_time(millisecond),
do_cleanup(Now, ?MAX_NUM),
cleaner_loop(State).
do_cleanup(Now, Max) ->
do_cleanup(Now, Max, ets:first(?PENDING_INDEX_TAB)).
do_cleanup(_Now, 0, _Key) ->
ok;
do_cleanup(_Now, _Max, '$end_of_table') ->
ok;
do_cleanup(Now, Max, ExpireAt) when ExpireAt =< Now ->
case ets:lookup(?PENDING_INDEX_TAB, ExpireAt) of
[{ExpireAt, Key}] ->
ets:delete(?PENDING_INDEX_TAB, ExpireAt),
ets:delete(?PENDING_TAB, Key),
do_cleanup(Now, Max - 1, ets:next(?PENDING_INDEX_TAB, ExpireAt));
[] ->
do_cleanup(Now, Max - 1, ets:next(?PENDING_INDEX_TAB, ExpireAt))
end;
do_cleanup(_Now, _Max, _ExpireAt) ->
ok.