vpndetection_cache (vpndetection v1.0.0)

View Source

The per-client result cache: an LRU with a TTL, owned by one process.

An ETS table dies with the process that created it, so a cache that is meant to outlive the code building the client needs an owner of its own. That owner is also the serialization point the LRU needs, because recency is kept in a second table that has to stay in step with the first.

Reads do NOT go through it. get/2 reads the entry table directly, so the N workers of a batch never queue behind one process to find out they have a hit.

Summary

Functions

Read an address, if it is held and still fresh.

Start a cache holding at most Max addresses for TtlMs each.

Types

cache/0

-type cache() :: #{pid := pid(), entries := ets:table()}.

Functions

get(_, Ip)

-spec get(cache(), binary()) -> {ok, vpndetection_result:result()} | miss.

Read an address, if it is held and still fresh.

A cache whose owner has gone answers miss rather than raising: a miss is always safe, and taking a caller's request path down because an optimization went away would not be.

handle_call(_, From, State)

handle_cast(_, State)

init(_)

put(_, Ip, Result)

-spec put(cache(), binary(), vpndetection_result:result()) -> ok.

start_link(Max, TtlMs)

-spec start_link(pos_integer(), pos_integer()) -> {ok, cache()}.

Start a cache holding at most Max addresses for TtlMs each.

Linked, so a cache cannot outlive the process that built the client and leak a process plus two ETS tables that nothing will ever collect. Build clients in something long lived, and call vpndetection:close/1 when done.

stop(_)

-spec stop(cache()) -> ok.

terminate(Reason, State)