[erlang-questions] Best way to implement a simple cache

Michael McDaniel <>
Wed Nov 11 18:15:56 CET 2009


On Wed, Nov 11, 2009 at 10:23:01AM -0600, Garrett Smith wrote:
> > On Nov 11, 2009, at 1:45 AM, Garrett Smith wrote:
> >
> >> On Tue, Nov 10, 2009 at 11:25 AM, Jachym Holecek <> wrote:
> >>> Hello,
> >>>
> >>> # Jan Vincent 2009-11-10:
> >>>> I wanted your take on how to implement a simple small key-value
> >>>> cache, maybe holding around a few hundred tuples. The thing is, I
> >>>> don't want the cache to be consuming all my memory so that entries
> >>>> in the cache expires if it isn't read for some time or some maximum
> >>>> size is met.
> >>>
> >>> An ETS table owned by a gen_server that runs periodic cleanup on it?
> >>>
> >>
> >> I find myself writing purpose built gen_servers that maintain the
> >> cache their state for this sort of thing. To 'expire' items in the
> >> cache, you could run another process as a timer that calls an expire
> >> method on the gen_server. There are more moving parts here, but
> >> they're decoupled and avoid using ETS for what's a pretty simple
> >> caching requirement.
> 
> On Wed, Nov 11, 2009 at 9:41 AM, Jan Vincent <> wrote:
> > Why wouldn't an ETS be good for this?
> 
> I'm sure it'd be fine for it :)
> 
> I personally like to avoid using the "global" structures for data
> management whenever I can get by with a process. I like being able to
> look at a function header and know that I'm seeing everything that
> could effect the result.
> 
> That said, I'm just not experienced with the various patterns in
> Erlang to have strong opinions either way. Just my inclination.
> 
> Garrett
> 
________________________________________________________________


 ets can be private to a particular process ; 



-module(session).

-export( [start/2, loop/2] ).


start( Name, Timeout ) -> spawn( fun() -> init( Name, Timeout ) end)  .
 

init( Name, Timeout )  ->
   register( Name, self() ) ,
   Tbl = Name ,

   ets:new( Tbl, [named_table, private] ) ,
   ets:insert( Tbl, {start, httpd_util:rfc1123_date()} ) ,

   ?MODULE:loop( Name, Timeout )

.%init/1



loop( Name, Timeout ) ->

   Tbl = Name ,
   [{start, Start}] = ets:lookup( Tbl, start) ,

   receive
      {From, _Msg} ->  
         io:fwrite("hello ~p, I started at: ~p~n", [From, Start]) ,

         loop( Name, Timeout )

      after Timeout ->
          io:fwrite("tired now, started at: ~p~n", [Start])

   end
.%loop/2


1> c(session).
2> session:start(fu, 10000).  
<0.42.0>
3> fu ! {self(), hello}.
hello <0.35.0>, I started at: "Wed, 11 Nov 2009 17:11:11 GMT"
{<0.35.0>,hello}
4> ets:lookup(fu, start).
** exception error: bad argument
     in function  ets:lookup/2
        called as ets:lookup(fu,start)
5>
tired now, started at: "Wed, 11 Nov 2009 17:11:11 GMT"



 $ erl  -man  ets


search for private



-- 
Michael McDaniel
Portland, Oregon, USA
http://trip.autosys.us



More information about the erlang-questions mailing list