Catalyst 模型是否只创建一次,然后在应用程序的整个生命周期中使用?还是$c->model()每次都新建一个Model类?
这取决于您对模型的实现。如果您的模型中有ACCEPT_CONTEXT 方法,Catalyst 将在您每次调用$c->model() 时创建一个新对象。如果没有,它将在应用程序启动期间实例化一次。这在 Initialization 下的Catalyst::Manual::Internals 中有记录。
在YAPC::EU 2016 in Cluj,Catalyst 的当前维护者 John Napiorkowski 进行了(远程)关于 Catalyst 的讨论,从from about 53 minutes into the talk 开始解释了这一方面。整件事以及他的其他演讲都值得一看。
如果我使用 fastcgi 运行我的应用程序并且有 6 个线程,这意味着我的应用程序的每个线程都将获得自己的模型类,并且必须进行查询并拥有 6 个单独的缓存,对吗?
我不确定那个。我相信它启动一次然后分叉。所以它会创建一个实例并将其复制到分支。
为您的方法使用 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's tracing output。它会将丰富多彩的查询转储到您的 Catalyst 日志中。
或者,CHI 非常适合构建事物的缓存,尽管在这里可能有点过头了。