| OurCal documentation | Contained in the OurCal distribution. |
OurCal::Provider::Cache - a caching provider
[a_cache]
type = cache
dir = .cache
child = a_provider
The directory to cache into. Defaults to '.cache'
An optional child to cache stuff from. This will instantiate the provider and feed stuff through to it, caching appropriately.
How long to cache for in seconds. Defaults to 1800 (30 mins).
Requires an OurCal::Config object as config param and a name param.
Retrieve the cache file and returns a list of objects serialised in it.
If the cache has expired then runs the subroutine passed to fetch more data.
Returns all the todos on the system.
Returns whether there are events given the params.
Returns all the events for the given params.
Returns the name of all the users on the system.
Save a todo.
Delete a todo.
Save an event.
Delete an event..
| OurCal documentation | Contained in the OurCal distribution. |
package OurCal::Provider::Cache; use strict; use File::Spec::Functions qw(catfile rel2abs); use File::Path; use Storable; use OurCal::Provider;
sub new { my $class = shift; my %what = @_; my $conf = $what{config}->config($what{name}); if (defined $conf->{child}) { $what{_provider} = OurCal::Provider->load_provider($conf->{child}, $what{config}); $what{_provider_name} = $conf->{child}; } $what{_cache_dir} = $conf->{dir} || '.cache'; $what{_cache_expiry} = $conf->{cache_expiry} || 60 * 30; return bless \%what, $class; } sub todos { my $self = shift; return $self->_do_cached('todos', @_); } sub has_events { my $self = shift; return ($self->_do_cached('has_events', @_))[0]; } sub events { my $self = shift; my %opts = @_; my @events = $self->_do_cached('events', %opts); @events = splice @events, 0, $opts{limit} if defined $opts{limit}; return @events; } sub users { my $self = shift; return $self->_do_cached('users', @_); } sub save_todo { my $self = shift; return $self->_do_default('save_todo', @_); } sub del_todo { my $self = shift; return $self->_do_default('del_todo', @_); } sub save_event { my $self = shift; return $self->_do_default('save_event', @_); } sub del_event { my $self = shift; return $self->_do_default('del_event', @_); } sub _do_cached { my $self = shift; my $sub = shift; my $thing = shift; return unless defined $self->{_provider}; my $file = $self->{_provider_name}."+".$sub."@".$self->_flatten_args($thing, @_); return $self->cache($file, sub { $self->{_provider}->$sub($thing, @_) }); }
# TODO perhaps the caching code should be refactored out into # ::Cache::Simple and ::Provider::Cache could take an optional # 'class' parameter. This will do for now though. sub cache { my $self = shift; my $file = shift; my $sub = shift; my $dir = rel2abs($self->{_cache_dir}); -d $dir || eval { mkpath($dir) } || die "Couldn't create cache directory $dir: $@\n"; my $cache = catfile($dir, $file); my $expire = $self->{_cache_expiry}; my $mtime = (stat($cache))[9]; my $time = time; my @res = (); if (-e $cache && ($time-$mtime < $expire)) { @res = @{Storable::retrieve( $cache )}; } else { @res = $sub->(); Storable::store( [@res], $cache ); } return @res; } sub _flatten_args { my $self = shift; my %opts = @_; my $flat = ""; foreach my $key (sort keys %opts) { $flat .= "$key=$opts{$key};" } return $flat; } sub _do_default { my $self = shift; my $sub = shift; my $thing = shift; return unless defined $self->{_provider}; return $self->{_provider}->$sub($thing, @_); }
1;