[erlang-questions] Best way to implement a simple cache
Michael McDaniel
erlangy@REDACTED
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 <freza@REDACTED> 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 <jvliwanag@REDACTED> 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