[Dbix-class] Caching a resultset?

Peter Rabbitson rabbit+dbic at rabbit.us
Wed Jan 16 12:20:55 GMT 2013


On Wed, Jan 16, 2013 at 11:03:43AM +0100, Alexander Hartmaier wrote:
> On 2013-01-15 21:49, Peter Rabbitson wrote:
> > On Tue, Jan 15, 2013 at 05:12:12PM +0100, Alexander Hartmaier wrote:
> >> On 2013-01-15 16:51, Peter Rabbitson wrote:
> >>> On Tue, Jan 15, 2013 at 10:09:19AM -0500, Jesse Sheidlower wrote:
> >>>> On Tue, Jan 15, 2013 at 05:18:06AM +1100, Peter Rabbitson wrote:
> >>>>> On Mon, Jan 14, 2013 at 11:07:34AM -0500, Jesse Sheidlower wrote:
> >>>>>>> So apart from the mystery around the nonsensical exception - does this help?
> >>>>>>>
> >>>>>>> local $DBIx::Class::ResultSourceHandle::thaw_schema = $c->model(...)->schema;
> >>>>>> Yes! Putting that before the "unless" seems to make everything work
> >>>>>> correctly.... Will be testing further this afternoon. Thanks!
> >>>>> Please let me know if wider testing is succesful.
> >>>> In one sense, wider testing was indeed successful. The RS was cached
> >>>> properly, it worked in several different environments, etc.
> >>>>
> >>>> However, it didn't "work" in one particularly crucial way, which in
> >>>> retrospect I'm surprised I didn't think about: the resultset may have
> >>>> been cached, but once I get it back, it's still just a resultset, so
> >>>> when I use it again in the template, it hits the database again. Every
> >>>> time.
> >>>>
> >>>> This is exactly what I wanted to avoid by this whole escapade.
> >>> You need to combine the above with [1] and/or [2].
> >>>
> >>> [1] https://metacpan.org/module/DBIx::Class::ResultSet#cache
> >>> [2] https://metacpan.org/module/DBIx::Class::ResultSet#set_cache
> >>>
> >>> Cheers
> >> You mean don't prefetch the relationships and populate it's cache after
> >> fetching all results?
> > Um... prefetch does not touch the cache of the *main* rs. I am not sure
> > what you mean above - explain.
> My schema has quite some 'side tables' like types, stati and so on. They
> almost never change.
> It would help performance if I could tell the schema to load all rows,
> cache them and populate a relationship from the cache when prefetched.
> For example
> 
> Interface->belongs_to('rel_interface_type', ::Interface_Type,
> 'fk_interface_type');
> 
> Schema->connect({
>     ... ,
>     prefetch => [qw( Interface_Type )],
> });

You are looking at the wrong layer.

1) At connection time tell the storage you *may* be using Cursor::Cached at
places: [1]

2) Add the appropriate cache_for attribute to the relationships you want to
add it to:
  Interface->belongs_to('rel_interface_type', ::Interface_Type,
    'fk_interface_type', {
      cache_object => do {
        # an instance of say Cache::FileCache, something that
        # understands get()[2] set()[3] and remove()[4]
        # sorry about the links to source, mst sucks at POD,
        # docpatches more than welcome
      },
      cache_for => do { # sub-argument to set as in [3] }
  ); 

3) Optionally register extra relationships )extra names) which never use 
the cache

This way it is just granular enough to be useful, and won't require you 
to change any of the actual app logic.

Cheers

[1] https://metacpan.org/source/ARCANEZ/DBIx-Class-Cursor-Cached-1.001002/lib/DBIx/Class/Cursor/Cached.pm#L101
[2] https://metacpan.org/source/ARCANEZ/DBIx-Class-Cursor-Cached-1.001002/lib/DBIx/Class/Cursor/Cached.pm#L77
[3] https://metacpan.org/source/ARCANEZ/DBIx-Class-Cursor-Cached-1.001002/lib/DBIx/Class/Cursor/Cached.pm#L79
[4] https://metacpan.org/source/ARCANEZ/DBIx-Class-Cursor-Cached-1.001002/lib/DBIx/Class/Cursor/Cached.pm#L86



More information about the DBIx-Class mailing list