Perl Catalyst DBIx Cursor Cache — как очистить?

извиняюсь и заранее благодарю за то, что, даже когда я печатаю, кажется, вероятно, глупым вопросом, но в любом случае.

У меня есть базовое приложение Catalyst, использующее DBIx::Class с "Автором" и связанной таблицей "Книга". Кроме того, я также использую 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'
                }
);
...

-- Определение MyApp::Controller::Author.pm с методом 'show_author_and_books' - набор результатов кэшируется.

...
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?

    ...
} 

Естественно, я знаю, что $author_and_books_rs, как определено в Author->show_author_and_books, содержит метод 'clear_cache', но, очевидно, это не так. области действия в Book->edit_do (не говоря уже о другой проблеме, которая может возникнуть).

Итак, это правильный подход, чтобы снова сделать запрос DBIx в соответствии с ...show_author_and_books, а затем снова вызвать 'clear_cache', или есть более прямой способ, где я могу просто сказать что-то вроде этого $c->cache->('DB::Author')->clear_cache?

Еще раз спасибо.

PS. Я уверен, когда я посмотрю на это завтра, меня поразит вся глупость вопроса :с


person user647248    schedule 08.02.2012    source источник


Ответы (3)


Пытаться

$c->model( 'DB::Author' )->clear_cache() ;
person dgw    schedule 08.02.2012
comment
спасибо за предложение, но, увы, это не работает, так как все данные из D::C::Cursor::Cached хранятся в одном пространстве имен (например, кеш будет содержать данные 'DB::Author', 'DB ::Books', 'DB::Other'), так что стирание очищает все. Мне нужно иметь возможность истечь либо для определенного набора, либо для определенного пространства имен, поэтому вместо этого я выбрал следующее решение. - person user647248; 14.02.2012

Решение, к которому я пришел в конце концов, заключалось в том, чтобы НЕ использовать DBIx::Class::Cursor::Cached, а вместо этого напрямую использовать подключаемый модуль Catalyst Cache, определяющий несколько внутренних кэшей для обработки различных пространств имен, которыми я пытаюсь управлять в реальном времени. мировой сценарий.

Я отказался от D::C::Cursor::Cached, поскольку все данные хранились/хранятся в одном и том же пространстве имен, плюс, по-видимому, не существует метода для истечения срока действия данных до уже установленного времени.

Итак, для полноты из приведенного выше кода определение MyApp::Model::DB.pm потеряет ключи/значения «черты» и «курсор_класс».

Потом...

Плагин MyApp.pm::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
                                                },
                                    ...            
                                   }
...                                   

-- Определение MyApp::Controller::Author.pm с методом 'show_author_and_books' - набор результатов кэшируется.

...
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;    

    ...
}

ПРИМЕЧАНИЕ. Как и следует ожидать от использования Author и компакт-дисков, это не реальный сценарий, над которым я работаю, но он должен служить для демонстрации моих намерений.

Поскольку я относительно новичок в чуде DBIx и действительно Catalyst, мне было бы интересно услышать, есть ли лучший подход к этому (я очень ожидаю, что есть), но на данный момент он будет служить, поскольку я пытаюсь для обновления устаревшего приложения.

person user647248    schedule 13.02.2012

Плагин, вероятно, можно было бы исправить, чтобы сделать кэши для каждого набора результатов простыми для пространства имен и очистки независимо, и, в качестве альтернативы, вероятно, было бы не так сложно добавить пространство имен к атрибутам. Если вы хотите поработать над этим хитом #dbix-class, и я буду готов вас наставлять - jnap

person John Napiorkowski    schedule 04.08.2014