Re: Documentation blues
[prev]
[thread]
[next]
[Date index for 2005/07/04]
At 9:44 AM -0400 6/21/05, Perrin Harkins wrote:
>On Tue, 2005-06-21 at 22:37 +1000, Jacinta Richardson wrote:
>> It's pretty clear that what is happening is that since the objects
>>my search is
>> turning up already exist in the global cache of objects they're not being
>> created and thus aren't gaining this new column value.
>
>This has been discussed on the list before. It's not hard to patch
>this, but it probably isn't a good idea, because data in objects you are
>already working with could get overwritten.
That comment got me thinking about caching...
I'm keeping a complex structure in memory across page loads because
it's expensive to build. I want to make sure all of the objects in
the structure have the latest data at the beginning of each page
load. I don't care about keeping changes from previous page loads
(there had better not be any, or I've forgotten to call update
somewhere).
I've added the code below to my base class, and I call
$class->refresh at the beginning of each page load for each class
that might be held in memory in my structure.
This doesn't handle deletes. They're rare in my usage, and I don't
want to add a 'deleted' column or a log table to track them. Instead,
I invalidate all of my stored structures if a delete happens.
Does this seem like a reasonable implementation? It seems to work,
but am I missing any obvious gotchas? I was going to add a wiki page
for this, but wanted to make sure I wasn't giving bad advice first.
__PACKAGE__->mk_classdata('_last_refresh');
__PACKAGE__->_last_refresh(Loath::Date->now);
__PACKAGE__->set_sql(refresh => <<"");
SELECT *
FROM __TABLE__
WHERE modified >= ?
# Makes sure that the objects in the live objects index all have the
latest data
# This *will* clobber any uncommitted changes you've made to these objects.
# This is useless if you're not holding data in the live objects index *and*
# some other structure, since the live objects index is not a cache.
sub refresh {
my ($class) = @_;
$now = Loath::Date->now;
#warn "refresh $class, last was " . $class->_last_refresh . "\n";
my $sth = $class->sql_refresh;
my $updates = 0;
$sth->execute("" . $class->_last_refresh);
foreach my $data ($sth->fetchall_hash) {
# can't access %Live_Objects directly because of scope
# have to use _init to get this, which might result in
# updating an object that wasn't in the index and then
# immediately throwing it away when $obj goes out of scope
my $obj = $class->_init($data);
$obj->_attribute_store($data);
$obj->call_trigger('select');
# warn "updated $class " . $obj->id . " modified at " . $obj->modified;
$updates++;
}
$class->_last_refresh($now);
return $updates;
}
--
Aneel Nazareth -- http://eye-of-newt.com/nazareth --