Re: retrieve() hits db even if obj present in %Live_Objects.
[prev]
[thread]
[next]
[Date index for 2004/06/24]
This is good. I actually was asking about this in the first place because
I've been trying to implement a cache layer of my own, but finding it
difficult to do without extraordinary workarounds.
There are special difficulties when the cache is of frozen CDBI objects.
(I've checked out Class::DBI::Cache, but it seems not to address these
difficulties, and also resorts to the same approach I was taking, which is
to override retrieve() and construct().)
What I'm trying to accomplish is a disk-based cache of frozen CDBI
instances, each entirely discrete from the other (and not storing inflated
or partially-inflated foreign members as attributes). Each is populated with
its Primaries and Essentials prior to being frozen (and to simplify the
problem, lazy inflation is not used). Relationships between them should all
work properly and as expected. db connections should be made only when a
needed item is not found in the cache -- and should be closed as soon as any
db lookup is complete. I'd like also to be able to disable lookups that are
*not* id-based (to avoid db connections), and to disable inserts, deletes,
and updates to the db.
I've got something working now, but it's not pretty.
Having a single point, designed to be overridden, through which all id-based
lookups pass, would make this task much easier. I think _init() is currently
the closest thing to this in CDBI, but there are some common lookup
mechanisms that circumvent it.
_do_search() suffers from (and underlies) the same problem that retrieve()
has -- Tim's patch will fix the problem with retrieve(), specifically, as I
understand. Still, will _do_search() be able to recognize an id-only lookup,
and try the cache before calling sql_Retrieve()? (Not that I care, actually,
if retrieve() works and I can disable non-id-based searches)
Another problem is has_a, which causes foreign-key attributes to be inflated
in place upon object instantiation, via _simple_bless. This is undesirable
for my purpose, because I'd much rather have 10 frozen albums that all
"point" to one artist, rather than 10 frozen albums that also carry 10
frozen copies of the same artist. This is wasteful, of course, and makes
purging that artist from the disk cache a pain. My solution here has been to
avoid using has_a, and to make sure that foreign-key attributes contain ids,
only, and to make sure that lookups on them are serviced through a (patched)
retrieve(). i.e: sub artist {
CDBI::Artist->retrieve($_[0]->_artist_accessor) }
Regarding closing the db connection after any db lookup: Is there a good
place in CDBI to do this? I've pretty much got everything rerouted through
my own retrieve(), and I'm doing a disconnect there, but I was thinking
there must be a more concise point deeper in the bowels of things.
An unrelated-but-related problem: How to set up a CDBI::Album::BASE class,
from which an industrial-strength CDBI::Album (your rank-and-file CDBI
class) and a lighter CDBI::Album::Cacheable class (containing some, but not
all, of the methods/data available to CDBI::Album) derive. Some of the
current CDBI class setup routines make this kind of thing tricky. (So if
anyone's read this far, and is remotely interested, I can blather on about
that, as well.)
Best regards,
TRL
>From: Perrin Harkins <perrin@xxxx.xxx>
>To: Tim Bunce <Tim.Bunce@xxxxx.xxx>
>CC: cdbi-talk@xxxxxx.xxxxx.xxx
>Subject: Re: retrieve() hits db even if obj present in %Live_Objects.
>Date: Thu, 24 Jun 2004 10:12:54 -0400
>
>Tim Bunce wrote:
>> - Fixes delete() to call $self->remove_from_object_index;
>
>Good thinking. +1 on the patch. This should make it easier to implement
>an actual cache layer for CDBI too.
>
>- Perrin