summaryrefslogtreecommitdiff
blob: 45b013c06054adfbd0186095523fe9b1e68d8921 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
-module(timed_cache_manager).
-export(
   [
      new/2,
      start/1,
      fetch/2
   ]
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%% Manager %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
manager_core_loop (DB) ->
   receive
      terminate -> ets:delete(DB)
   end.

new_database (DB) ->
   ets:new(
      DB,
      [
         set,
         public,
         {keypos, 1},
         {read_concurrency, true}
      ]
   ).

%%%% Timer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
timer_cleanup (DB, ObjectID) ->
   ets:delete(DB, ObjectID).

timer_core_loop (DB, ObjectID, Timeout) ->
   receive
      ok -> timer_core_loop(DB, ObjectID, Timeout);
      terminate -> ok
   after Timeout ->
      timer_cleanup(DB, ObjectID)
   end.

add_timer (DB, ObjectID, Timeout) ->
   spawn(timed_cache_manager, timer_core_loop, [DB, ObjectID, Timeout]).

add_to_cache (DB, ObjectID) ->
   TimerPID = add_timer(DB, ObjectID, 60000),
   Data = nothing, %% Do the actual NoSQL Fetch here.
   ets:insert(DB, {ObjectID, TimerPID, Data}),
   Data.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
new (Manager, DB) ->
   register(
      Manager,
      spawn(
         timed_cache_manager,
         start,
         [DB]
      )
   ).

start (DB) ->
   new_database(DB),
   manager_core_loop(DB).

fetch (DB, ObjectID) ->
   case ets:lookup(DB, ObjectID) of
      [] ->
         add_to_cache(DB, ObjectID);

      [{_, TimerPID, Data}] ->
         TimerPID ! ok,
         Data
   end.