% @doc storing map #{cookie := Context} -module(fd_cache). -behavior(gen_server). -export([ start_link/0, query/1, set/2, unset/1, %%--- %% everything below here runs in process context %%-- %% gen_server callbacks init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2 ]). -include("$zx_include/zx_logger.hrl"). -type context() :: wfc_eval_context:context(). -record(s, {cookies = #{} :: #{Cookie :: binary() := context()}}). % -type state() :: #s{}. %%-------------------------------- %% api (runs in context of caller) %%-------------------------------- -spec start_link() -> {ok, pid()} | {error, term()}. start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, none, []). -spec query(Cookie) -> {ok, Context} | error when Cookie :: binary(), Context :: context(). query(Cookie) -> gen_server:call(?MODULE, {query, Cookie}). -spec set(Cookie, Context) -> ok when Cookie :: binary(), Context :: context(). set(Cookie, Context) -> gen_server:cast(?MODULE, {set, Cookie, Context}). -spec unset(Cookie) -> ok when Cookie :: binary(). unset(Cookie) -> gen_server:cast(?MODULE, {unset, Cookie}). %%---------------------- %% gen-server bs %%---------------------- init(none) -> log(info, "starting fd_cache"), InitState = #s{}, {ok, InitState}. handle_call({query, Cookie}, _, State) -> Result = do_query(Cookie, State), {reply, Result, State}; handle_call(Unexpected, From, State) -> tell("~tp: unexpected call from ~tp: ~tp", [?MODULE, Unexpected, From]), {noreply, State}. handle_cast({set, Cookie, Context}, State) -> NewState = do_set(Cookie, Context, State), {noreply, NewState}; handle_cast({unset, Cookie}, State) -> NewState = do_unset(Cookie, State), {noreply, NewState}; handle_cast(Unexpected, State) -> tell("~tp: unexpected cast: ~tp", [?MODULE, Unexpected]), {noreply, State}. handle_info(Unexpected, State) -> tell("~tp: unexpected info: ~tp", [?MODULE, Unexpected]), {noreply, State}. code_change(_, State, _) -> {ok, State}. terminate(_, _) -> ok. %%--------------------- %% doers %%--------------------- do_set(Cookie, Context, State = #s{cookies = Cookies}) -> NewCookies = maps:put(Cookie, Context, Cookies), NewState = State#s{cookies = NewCookies}, NewState. do_unset(Cookie, State = #s{cookies = Cookies}) -> NewCookies = maps:remove(Cookie, Cookies), NewState = State#s{cookies = NewCookies}, NewState. do_query(Cookie, _State = #s{cookies = Cookies}) -> maps:find(Cookie, Cookies).