Perl Catalyst DBIx游标缓存 - 如何清除?

时间:2012-02-08 23:03:22

标签: perl caching catalyst dbix-class

道歉并提前感谢,即使在我打字的时候,看起来很可能是一个愚蠢的问题,但无论如何都要进行。

我有 DBIx :: Class 的基本 Catalyst 应用程序,其中包含“作者”和关联的“书籍”表。此外,我还使用 DBIx :: Class :: Cursor :: Cached 来适当地缓存数据。

问题是,在编辑之后,我需要在实际到期之前清除缓存数据 1.) Author-> show_author_and_books ,用于获取和缓存结果集。

2。) Book-> edit_do ,需要清除 Author-> show_author_and_books 请求中的缓存数据。

请参阅下面的基本/适当设置。

- MyApp.pm定义,包括后端'Cache :: FileCache'缓存。

__PACKAGE__->config(
name         => 'MyApp',
...

'Plugin::Cache' => {   'backend' => { class              => 'Cache::FileCache',
                                      cache_root         => "./cache",
                                      namespace          => "dbix",
                                      default_expires_in => '8 hours',
                                      auto_remove_stale  => 1
                                    }
                   },
...

- MyApp :: Model :: DB定义,使用'DBIx :: Class :: Cursor :: Cached'设置'缓存'特征。

...
__PACKAGE__->config(
schema_class => 'MyApp::Schema',

traits       => [ 'Caching' ],

connect_info => { dsn          => '<dsn>',
                  user         => '<user>',
                  password     => '<password>',
                  cursor_class => 'DBIx::Class::Cursor::Cached'
                }
);
...

- 使用'show_author_and_books'方法的MyApp :: Controller :: Author.pm定义 - 缓存结果集。

...
sub show_author_and_books :Chained('base') :PathPart('') :Args(0)
{
    my ( $self, $c ) = @_;

    my $author_id = $c->request->params->{author_id};

    my $author_and_books_rs = $c->stash->{'DB::Author'}->search({ author_id => $author_id },
                                                            { prefetch  =>  'book' },
                                                              cache_for =>  600 } ); # Cache results for 10 minutes.

    # More interesting stuff, but no point calling $author_and_books_rs->clear_cache here, it would make no sense:s
    ...

}

...    

- MyApp :: Controller :: Book.pm定义,使用“ edit_do ”方法更新图书条目,从而使 show_author_and_books 中的缓存数据无效。

...
sub edit_do :Chained('base') :PathPart('') :Args(0)
{
    my ( $self, $c ) = @_;

    # Assume stash contains a book for some author, and that we want to update the description.

    my $book = $c->stash->{'book'}->update({ desc => $c->request->params->{desc} });

    # How do I now clear the cached DB::Author data to ensure the new desc is displayed on next request to 'Author->show_author_and_books'?

    # HOW DO I CLEAR CACHED DB::Author DATA?

    ...
} 

当然,我知道作者 - &gt; show_author_and_books 中定义的 $ author_and_books_rs 包含一个方法' clear_cache ',但是显然这超出了 Book-&gt; edit_do 的范围(更不用说可能存在的另一个问题)。

那么,按照 ... show_author_and_books 再次发出DBIx请求是正确的方法,然后再次调用'clear_cache'或者是否有更直接的方法我可以说类似这样的$ c-&gt; cache-&gt;('DB :: Author') - &gt; clear_cache?

再次感谢你。

PS。我敢肯定,当我明天看到这个问题时,问题的完全愚蠢将会打击我:s

3 个答案:

答案 0 :(得分:0)

尝试

$c->model( 'DB::Author' )->clear_cache() ;

答案 1 :(得分:0)

我最终使用的解决方案是不使用'DBIx :: Class :: Cursor :: Cached',而是直接使用定义多个的Catalyst Cache插件 后端缓存来处理我试图在现实场景中管理的不同命名空间。

我退出了D :: C :: Cursor :: Cached,因为所有数据都保存在同一名称空间中,而且似乎没有一种方法可以使数据到期 时间已经确定。

为了完整起见,从上面的代码中,MyApp :: Model :: DB.pm定义将丢失'traits'和'cursor_class'键/值。

则...

MyApp.pm Plugin :: Cache'将扩展为包含多个缓存命名空间......

-- MyApp.pm definition including backend 'Cache::FileCache' cache.

... 
'Plugin::Cache' => { 'backends' => { Authors => { class              => 'Cache::FileCache',
                                                  cache_root         => "./cache",
                                                  namespace          => "Authors",
                                                  default_expires_in => '8 hours',
                                                  auto_remove_stale  => 1
                                                },
                                     CDs  => { class                     => 'Cache::FileCache',
                                                      cache_root         => "./cache",
                                                      namespace          => "CDs",
                                                      default_expires_in => '8 hours',
                                                      auto_remove_stale  => 1
                                                },
                                    ...            
                                   }
...                                   

- 使用'show_author_and_books'方法的MyApp :: Controller :: Author.pm定义 - 缓存结果集。

...
sub show_author_and_books :Chained('base') :PathPart('') :Args(0)
{
    my ( $self, $c ) = @_;

    my $author_id = $c->request->params->{author_id};

    my $author = $c->get_cache_backend('Authors')->get( $author_id );

    if( !defined($author) )
    {
        $author = $c->stash->{'DB::Author'}->search({ author_id => $author_id },
                                                    { prefetch  =>  'book', rows => 1 } )->single;

        $c->get_cache_backend('Authors')->set( $author_id, $author, "10 minutes" );
    }                                                              

    # More interesting stuff, ...
    ...
}

... 

- MyApp :: Controller :: Book.pm定义,使用'edit_do'方法更新书籍条目,从而使show_author_and_books中的缓存数据无效。

...
sub edit_do :Chained('base') :PathPart('') :Args(0)
{
    my ( $self, $c ) = @_;

    # Assume stash contains a book for some author, and that we want to update the description.

    my $book = $c->stash->{'book'}->update({ desc => $c->request->params->{desc} });

    # How do I now clear the cached DB::Author data to ensure the new desc is displayed on next request to 'Author->show_author_and_books'?

    # HOW DO I CLEAR CACHED DB::Author DATA? THIS IS HOW, EITHER...

    $c->get_cache_backend('Authors')->set( $c->stash->{'book'}->author_id, {}, "now" ); # Expire now.

    # ... OR ... THE WHOLE Authors namespace...

    $c->get_cache_backend('Authors')->clear;    

    ...
}

注意:正如您对使用作者和CD所期望的那样,这不是我正在使用的真实场景,但应该用来表明我的意图。

由于我对DBIx和Catalyst的奇迹相对较新,我有兴趣听听是否有更好的方法(我非常期待),但它会暂时用作我我试图更新遗留应用程序。

答案 2 :(得分:0)

可能会修补插件以使每个结果集缓存易于命名空间和独立清除,或者可能不会很难为属性添加命名空间。如果你想工作#dbix-class,我愿意指导你 - jnap