2016-10-04 8 views
2

私はCatalystアプリケーションを作成していますが、値が変更されない小さな設定テーブルを表すModelがあります。毎回これをデータベースに照会するのではなく、その応答をキャッシュしたいと思います。モデル内ではDBIx::Classを使用していますが、これはオプションのように見えるDBIx::Class::Cursor::Cachedが表示されました。Catalystモデルのキャッシュdbixコール

しかし、私がやったことは、Memoizeを使用して私のモデルの戻り値をキャッシュしていたことです。

  1. Catalystモデルは一度しか作成されず、アプリケーションの存続期間中に使用されますか?または、毎回$c->model()新しいModelクラスを作成しますか?

  2. 私はfastcgiでアプリケーションを実行していて、6つのスレッドがある場合、これは自分のアプリケーションの各スレッドが独自のモデルクラスを取得し、クエリを作成して6つの別々のキャッシュを持つ必要があることを意味します。

これは悪い解決策ですか?私は別のことをしなければならないでしょうか?

答えて

2

Catalystモデルは一度しか作成されず、アプリケーションの存続期間中に使用されますか?または、毎回$c->model()新しいModelクラスを作成しますか?

これは、モデルの実装によって異なります。モデルにACCEPT_CONTEXTメソッドがある場合、Catalystは$c->model()を呼び出すたびに新しいオブジェクトを作成します。そうでない場合は、アプリケーションの起動時に一度インスタンス化されます。それはCatalyst::Manual::Internalsの下に文書化されています。

YAPC::EU 2016 in Clujで、現在のCatalystのメンテナであるJohn Napiorkowskiが、この非常にアスペクトを説明しているCatalystについて(リモートの)トークをfrom about 53 minutes into the talkで開始しました。全体のことだけでなく、彼の他の話は見て価値があります。

私はFastCGIをして自分のアプリケーションを実行していることだし、6つのスレッドがある場合は、これは私のアプリの各スレッドは、独自のモデルクラスを取得し、正しい、クエリとhapve 6別々のキャッシュをしなければならないことを意味しますか?

私はそのことについてはわかりません。私はそれが一度始まり、その後勃発すると信じています。したがって、1つのインスタンスが作成され、フォークにコピーされます。使用


DBIx ::クラス::カーソル::それがうまくいくようにあなたのアプローチのためにキャッシュされたに見えます。 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 's tracing outputを有効にすることができます。カラフルなクエリをCatalystログにダンプします。また


ここでそれはおそらく、少し行き過ぎだけれども、CHIは、物事のキャッシュを構築するために素晴らしいです。

+0

徹底的な答えをありがとう!私は起動時にデータベースから取得し、それを使用するというアプローチが好きです。これはまさに私が探していたものでした。あなたがMemoizeを使うよりも良い解決策だと思いますか?または、悪い解決策をメモに記入していますか?本質的にそれは非常に似たような方法で働くので、ハッシュを作成するだけです。オブジェクトが構築された後はすべてキャッシュされているので、自分のソリューションが気に入っていると思います。あなたの考えに興味があるだけです。 – srchulo

+0

@src私はそれが悪い解決策ではないと思うし、常に複数の方法がありますが、それは別の目的のために作られています。私は最も簡単な方法で行くだろう。 Moose属性を使うことはとても自然なことです。それは依存関係を追加せず、使いやすいです。私はそのアプローチをファイルからのデータで多く使用しています。 – simbabque

+0

素晴らしいです。それは私がすることです。ありがとう! – srchulo

関連する問題