Catalyst 模型缓存 dbix 调用
Catalyst Model cache dbix calls
我正在写一个 Catalyst application and I have a Model that represents a small settings table whose values won't change. Rather than querying the database for this every time, I would like to cache the responses. Within the model I am using DBIx::Class, and I did see this DBIx::Class::Cursor::Cached,它看起来像一个选项。
然而,我最终做的是使用 Memoize 在我的模型中缓存 return 值。我对这个解决方案有两个问题:
Catalyst 模型是否只创建一次,然后在应用程序的整个生命周期内使用?还是 $c->model()
每次都创建一个新模型 class?
如果我 运行 我的应用程序有 fastcgi 并且有 6 个线程,这意味着我的应用程序的每个线程都会有自己的模型 class 并且会有进行查询并拥有 6 个独立的缓存,对吗?
这是一个糟糕的解决方案吗?我应该做点别的吗?
Are Catalyst Models only created once, and then used for the lifetime of the application? Or does $c->model()
create a new Model class each time?
这取决于您对模型的实施。如果在 Initialization 下有一个 ACCEPT_CONTEXT
method in your model, Catalyst will make a new object every time you call $c->model()
. If not, it will be instantiated once during startup of the application. That's documented in Catalyst::Manual::Internals。
在 YAPC::EU 2016 in Cluj the current maintainer of Catalyst, John Napiorkowski, gave a (remote) talk about Catalyst that explains this very aspect starting from about 53 minutes into the talk。整个事情以及他在那里的其他谈话都值得一看。
If I'm running my application with fastcgi and there are 6 threads, this means that each thread of my app will get its own model class and will have to make queries and hapve 6 separate caches, correct?
我不确定那个。我相信它启动一次然后分叉出来。所以它会创建一个实例并将其复制到分叉。
使用 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 非常适合构建事物的缓存,尽管在这里可能有点矫枉过正。
我正在写一个 Catalyst application and I have a Model that represents a small settings table whose values won't change. Rather than querying the database for this every time, I would like to cache the responses. Within the model I am using DBIx::Class, and I did see this DBIx::Class::Cursor::Cached,它看起来像一个选项。
然而,我最终做的是使用 Memoize 在我的模型中缓存 return 值。我对这个解决方案有两个问题:
Catalyst 模型是否只创建一次,然后在应用程序的整个生命周期内使用?还是
$c->model()
每次都创建一个新模型 class?如果我 运行 我的应用程序有 fastcgi 并且有 6 个线程,这意味着我的应用程序的每个线程都会有自己的模型 class 并且会有进行查询并拥有 6 个独立的缓存,对吗?
这是一个糟糕的解决方案吗?我应该做点别的吗?
Are Catalyst Models only created once, and then used for the lifetime of the application? Or does
$c->model()
create a new Model class each time?
这取决于您对模型的实施。如果在 Initialization 下有一个 ACCEPT_CONTEXT
method in your model, Catalyst will make a new object every time you call $c->model()
. If not, it will be instantiated once during startup of the application. That's documented in Catalyst::Manual::Internals。
在 YAPC::EU 2016 in Cluj the current maintainer of Catalyst, John Napiorkowski, gave a (remote) talk about Catalyst that explains this very aspect starting from about 53 minutes into the talk。整个事情以及他在那里的其他谈话都值得一看。
If I'm running my application with fastcgi and there are 6 threads, this means that each thread of my app will get its own model class and will have to make queries and hapve 6 separate caches, correct?
我不确定那个。我相信它启动一次然后分叉出来。所以它会创建一个实例并将其复制到分叉。
使用 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 非常适合构建事物的缓存,尽管在这里可能有点矫枉过正。