道歉并提前感谢,即使在我打字的时候,看起来很可能是一个愚蠢的问题,但无论如何都要进行。
我有 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
答案 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