Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add `no_defaults_for' attribute to fix subcache get/set infinite recursion #24

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tomeon
Copy link

@tomeon tomeon commented Jul 10, 2016

CHI subclasses that define one or more subcaches using defaults, namespace, or storage are susceptible to infinite recursion upon get and set. Consider l1_loop.pl:

#!/usr/bin/env perl

use strict;
use warnings;

package My::CHI;                                   

use base 'CHI';                                    

__PACKAGE__->config({                              
    storage => {                                   
        local_file => {                                  
            driver      => 'File',                 
            root_dir    => '/tmp/mychi',           
        },
        raw_memory => {
               driver => 'RawMemory',
               global => 0,
        },                                       
    },                                             
    defaults => {                                  
        storage => 'local_file',                         
        l1_cache    => {                           
            storage => 'raw_memory',                     
        },                                         
    },                                             
});                                                

package main;                                      

my $cache = My::CHI->new;                          
$cache->set('it', 'off');
$ ./l1_loop.pl
Deep recursion on subroutine "Role::Tiny::_COMPOSABLE::CHI::Driver::Role::HasSubcaches::set" at /home/matt/git/perl-chi/lib/CHI/Driver/Role/HasSubcaches.pm line 88.
Deep recursion on anonymous subroutine at (eval 42) line 16.
^C

The reason is that the subcache is instantiated using the same defaults as the parent cache, so will have its own subcache, which has its own subcache, which has its own subcache, all the way down. This manifests as recursion on the anonymous subroutines defined with before and around in CHI::Driver::Role::HasSubcaches.

This pull requests addresses the infinite recursion issue by adding the constructor param no_defaults_for, which allows specifying a list of keys to delete from the defaults, namespace, and storage hashrefs prior to instantiating a CHI subclass instance. All subcaches get l1_cache and mirror_cache automatically appended to no_defaults_for -- only the parent cache can have subcaches defined from package defaults.

Thanks in advance for considering this pull request!


P.S.: I got the following error when running dzil build:

$ dzil build
Can't call method "content" on an undefined value at /home/matt/opt/perl5/perlbrew/perls/perl-5.20.0/lib/site_perl/5.20.0/Dist/Zilla/Plugin/MakeMaker.pm line 318.

I fixed this by editing dist.ini to remove filenames = Makefile.PL from [PruneFiles] and add exclude_filename = Makefile.PL to [GatherDir]. The real culprit might be some environment muck-up on my part -- please let me know :).

by adding the `no_defaults_for` constructor attribute, which (a) permits
specifying a list of keys to delete from the `defaults`, `namespace`,
and `storage` hashrefs prior to instantiating a CHI subclass instance,
and (b) mandatorily contains the keys `l1_cache` and `mirror_cache`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant