| summaryrefslogtreecommitdiff | 
diff options
| author | nsensfel <SpamShield0@noot-noot.org> | 2018-07-11 18:02:26 +0200 | 
|---|---|---|
| committer | nsensfel <SpamShield0@noot-noot.org> | 2018-07-11 18:02:26 +0200 | 
| commit | acb9dd3220a3edcac93aa11d1d74d008e2fb23ed (patch) | |
| tree | 98b45af3f7eb9c7d812ed33a07e6a0f665a7a8cd /src/shared/io/shr_timed_cache.erl | |
| parent | fde827cba1ff3d889135c74ee1978098465fd200 (diff) | |
"sh_" -> "shr_".
Diffstat (limited to 'src/shared/io/shr_timed_cache.erl')
| -rw-r--r-- | src/shared/io/shr_timed_cache.erl | 130 | 
1 files changed, 130 insertions, 0 deletions
| diff --git a/src/shared/io/shr_timed_cache.erl b/src/shared/io/shr_timed_cache.erl new file mode 100644 index 0000000..b89de48 --- /dev/null +++ b/src/shared/io/shr_timed_cache.erl @@ -0,0 +1,130 @@ +-module(shr_timed_cache). +-behavior(gen_server). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% 'gen_server' Exports +-export +( +   [ +      init/1, +      handle_cast/2, +      handle_call/3, %% No reply will ever be given. +      terminate/2, +      code_change/3, +      format_status/2, +      handle_info/2 +   ] +). + +%%%% Actual Interface +-export +( +   [ +      fetch/3, +      update/4, +      invalidate/3 +   ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec add_to_cache (atom(), any(), any()) -> any(). +add_to_cache (DB, Owner, ObjectID) -> +   {ok, TimerPID} = gen_server:start(?MODULE, {DB, {Owner, ObjectID}}, []), +   {ok, Data} = shr_database:fetch(DB, ObjectID), +   ets:insert(DB, {{Owner, ObjectID}, TimerPID, Data}), +   Data. + +-spec add_update_to_cache (atom(), any(), any(), any()) -> 'ok'. +add_update_to_cache (DB, Owner, ObjectID, Data) -> +   {ok, TimerPID} = gen_server:start(?MODULE, {DB, {Owner, ObjectID}}, []), +   ets:insert(DB, {{Owner, ObjectID}, TimerPID, Data}), +   ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% 'gen_server' functions +init ({DB, ObjectID}) -> +   io:format("~nCache entry added: ~p.~n", [{DB, ObjectID}]), +   {ok, {DB, ObjectID}, shr_timed_caches_manager:get_timeout()}. + +handle_call (invalidate, _, State) -> +   {stop, normal, State}; +handle_call (ping, _, State) -> +   {noreply, State, shr_timed_caches_manager:get_timeout()}. + +handle_cast (invalidate, State) -> +   {stop, normal, State}; +handle_cast (ping, State) -> +   {noreply, State, shr_timed_caches_manager:get_timeout()}. + +terminate (_, {DB, ObjectID}) -> +   io:format +   ( +      "~nCache entry timed out or was invalidated: ~p.~n", +      [{DB, ObjectID}] +   ), +   ets:delete(DB, ObjectID). + +code_change (_, State, _) -> +   {ok, State}. + +format_status (_, [_, State]) -> +   [{data, [{"State", State}]}]. + +handle_info(timeout, State) -> +   {stop, normal, State}; +handle_info(_, {DB, ObjectID}) -> +   {noreply, {DB, ObjectID}, shr_timed_caches_manager:get_timeout()}. + +%%%% Interface Functions +-spec fetch (atom(), any(), any()) -> any(). +fetch (DB, Owner, ObjectID) -> +   io:format("~nfetch from cache: ~p.~n", [{DB, {Owner, ObjectID}}]), +   case ets:lookup(DB, {Owner, ObjectID}) of +      [] -> add_to_cache(DB, Owner, ObjectID); + +      [{_, TimerPID, Data}] -> +         gen_server:cast(TimerPID, ping), +         Data +   end. + +-spec update (atom(), any(), any(), any()) -> 'ok'. +update (DB, Owner, ObjectID, Data) -> +   io:format("~nUpdating cache: ~p.~n", [{DB, {Owner, ObjectID}}]), +   case ets:lookup(DB, {Owner, ObjectID}) of +      [] -> ok; + +      [{_OwnerID, TimerPID, _Data}] -> +         gen_server:stop(TimerPID) +   end, +   add_update_to_cache(DB, Owner, ObjectID, Data). + +-spec invalidate (atom(), any(), any()) -> 'ok'. +invalidate (DB, Owner, ObjectID) -> +   case ets:lookup(DB, {Owner, ObjectID}) of +      [] -> +         io:format +         ( +            "~nInvalidation request on non-stored entry: ~p.~n", +            [{DB, Owner, ObjectID}] +         ), +         ok; + +      [{_, TimerPID, _}] -> +         io:format +         ( +            "~nInvalidation request on stored entry: ~p.~n", +            [{DB, Owner, ObjectID}] +         ), +         gen_server:stop(TimerPID), +         ok +   end. | 


