Catalyst模型缓存dbix调用



我正在编写一个Catalyst应用程序,我有一个模型,它表示一个小的设置表,其值不会改变。我希望缓存响应,而不是每次都为此查询数据库。在模型中,我使用的是DBIx::Class,我确实看到了这个DBIx::Class::Cursor::Cached,它看起来像一个选项。

然而,我最终做的是使用Memoize在我的模型中缓存返回值。对于这个解决方案,我有两个问题:

  1. 催化剂模型是否只创建一次,然后在应用程序的生命周期内使用?或者$c->model()每次都创建一个新的Model类?

  2. 如果我用fastcgi运行我的应用程序,有6个线程,这意味着我的应用程序的每个线程将得到自己的模型类,将不得不进行查询,并有6个单独的缓存,正确吗?

这是一个坏的解决方案吗?我应该做点别的吗?

催化剂模型是否只创建一次,然后在应用程序的生命周期内使用?或者$c->model()每次都创建一个新的Model类?

这取决于你对模型的实现。如果模型中有ACCEPT_CONTEXT方法,每次调用$c->model()时,Catalyst都会生成一个新对象。如果没有,它将在应用程序启动时实例化一次。这在Initialization下的Catalyst::Manual::Internals中有记录。

在克鲁日举行的YAPC::EU 2016上,Catalyst的现任维护者John Napiorkowski做了一个关于Catalyst的(远程)演讲,从53分钟开始就解释了这方面。整个事件以及他在那里的其他演讲都值得一看。

如果我用fastcgi运行我的应用程序,有6个线程,这意味着我的应用程序的每个线程将得到自己的模型类,将不得不进行查询,并有6个单独的缓存,正确吗?

我不确定那个。我相信它会启动一次,然后岔开。因此,它将创建一个实例并将其复制到fork。


对于您的方法使用DBIx::Class::Cursor::Cached看起来会起作用。如果您需要DBIx::Class ResultSet对象,那很好。如果没有,您可以将结果作为惰性属性附加到模型上。它可以看起来像这样:

package My::Model;
use Mooose;
use My::DB::Schema;
extends 'Catalyst::Model';
has stuff => (
    is => 'ro',
    isa => 'HashRef',
    traits => ['Hash'],
    handles => {
        has_stuff => 'exists',
        get_stuff => 'get',
        # ...
    },
    lazy => 1,
    builder => '_build_stuff',
);
sub _build_stuff {
    my ($self) = @_;
    # get stuff from the DB here, convert it to a config hash
    # or whatever you need and store it in our stuff attribute
    # that works well if your config looks something like this:
    # {
    #     color => 'red',
    #     price => 13.37,
    #     things => [ qw/ foo bar baz / ],
    #     # ...
    # }
    # you can then use the Hash trait on your attribute to access it
}
1;

这样它会在你第一次使用它时加载它,然后你就完成了。它会被存储在对象中。

如果您想调查这是否实际工作并且不做更多查询,您可以使用DBIC_TRACE=1环境变量打开DBIC的跟踪输出。它将把彩色查询转储到您的Catalyst日志中。


或者,CHI非常适合构建事物的缓存,尽管在这里可能有点过头了。

最新更新