2017-01-19 5 views
2

私は現在、Mojoliciousを使用して小さな単一ページのWebアプリケーションを開発しています。このアプリには、REST-ish APIと通信するJavascriptフロントエンド(バックボーンを使用)があります。元のレイアウトは、おおよそである:Mojoliciousテンプレートキャッシュが古くなっています

use Mojolicious::Lite; 

# ... setup code ... 

get '/' => sub { 
    my $c = shift; 
    # fetch+stash data for bootstrapped collections... 
    $c->render('app_template'); 
}; 

get '/api_endpoint' => sub { 
    my $c = shift; 
    # fetch appropriate API data... 
    $c->render(json => $response); 
}; 

# ... more API endpoints ... 

app->start; 

アプリテンプレートは、EPを使用し、非常に最小限。唯一のサーバ側のテンプレートディレクティブは、ブートストラップされたコレクション用のJSONを挿入するだけです。それはプレーンなCGIスクリプトとしてApache経由で配備されています。 (これは最適ではありませんが、トラフィックの少ない内部使用に適しており、より複雑なサーバー構成では問題があります)Perl CGIはmod_perlで設定されています。

これはほとんどの場合動作しますが、レンダラーがテンプレートをキャッシュしてその変更を無視するという考えが何らかの形で得られることがあります。 error_logのデバッグレコードには、通常の「レンダリングテンプレート」ではなく「キャッシュされたテンプレートのレンダリング」が表示され、テンプレートに対する新しい変更がブラウザに表示されなくなります。私はこれを止めるための信頼できる方法を見つけることができませんが、それは最終的に私が見分けることができない状況に応じてそれ自身で止まるでしょう。

アプリ通知テンプレートの変更を確実に行うにはどうすればよいですか?あるいは、テンプレートのキャッシュを完全に無効にするにはどうすればよいですか?

+0

あなたはtime_をほとんどの_worksで私を持っていました。 :) – simbabque

答えて

5

アプリ通知テンプレートの変更を確実にするにはどうすればよいですか?

これはmorbo開発サーバーのためのものです。 Morboは、ライブコードの展開には使用されませんが、コードとテンプレートを継続的に変更する開発環境には使用されません。通常、ライブコードとテンプレートの変更は、アプリケーションサーバーまたはApacheを再起動することによって処理されます。

また、テンプレートのキャッシュを完全に無効にするにはどうすればよいですか?

はこれを行うには、(use Mojolicious::Lite後、ルートの外に)次のセットアップコードを追加します。

app->renderer->cache->max_keys(0); 
+0

私は特別なことなしにこの環境で開発をしてきました。理論的にはCGI環境なので、新しいページのロードにはそれぞれ独自のプロセスが必要です。私はmod_perlが何とかその不変量を破ると思う。いずれにせよ、キャッシュを無効にすることは有効です。 –

3

古い回答については下記を参照してください。

IRCのGrinnzについて議論した後、私はこの回答の結果をプラグインに入れて、Mojolicious::Plugin::Renderer::WithoutCacheとしてCPANでリリースしました。

あなたはこのようにそれを使用することができます:

use Mojolicious::Lite; 
plugin 'Renderer::WithoutCache'; 

それは何もしない新しいキャッシュオブジェクトを作成し、レンダリングにグローバルことをインストールします。そうすれば、私の最初の答えのように毎回作成する必要はありません。

理論的には、これがあるべきより速いGrinnz' approach(もっと賢明である)、そしてあなたが明示的にキャッシュにしたくないから、あなたは明らかに物事が右に、可能な限り高速になりたいですか?実際のMojo :: Cacheはまだキャッシュを設定しようとする必要がありますが、空きキーがなくなるたびに中断し、毎回キャッシュから値を検索しようとするため、おそらく早いでしょう。

DumbbenchBenchmarkの両方でこれをベンチマークしました。両方とも無視できる結果を示した。私はそれらを数回走らせましたが、それらは多く変動しました。そして、どちらが速いのかは明らかではありません。私は実装の速いところで実行の出力を含めましたが、それはまだ違いがどれほど小さいかを示しています。 Dumbbenchと

ベンチマーク:ベンチマークと

use Dumbbench; 
use Mojolicious::Renderer; 
use Mojolicious::Controller; 
use Mojolicious::Plugin::Renderer::WithoutCache::Cache; 

my $controller   = Mojolicious::Controller->new; 
my $renderer_zero_keys = Mojolicious::Renderer->new; 
$renderer_zero_keys->cache->max_keys(0); 

my $renderer_nocache = Mojolicious::Renderer->new; 
$renderer_nocache->cache(Mojolicious::Plugin::Renderer::WithoutCache::Cache->new); 

my $bench = Dumbbench->new(
    target_rel_precision => 0.005, 
    initial_runs   => 5000, 
); 

$bench->add_instances(
    Dumbbench::Instance::PerlSub->new(
     name => 'max_keys', 
     code => sub { 
      $renderer_zero_keys->render($controller, { text => 'foobar' }); 
     } 
    ), 
    Dumbbench::Instance::PerlSub->new(
     name => 'WithoutCache', 
     code => sub { 
      $renderer_nocache->render($controller, { text => 'foobar' }); 
     } 
    ), 
); 

$bench->run; 
$bench->report; 

__END__ 
max_keys: Ran 8544 iterations (3335 outliers). 
max_keys: Rounded run time per iteration: 5.19018e-06 +/- 4.1e-10 (0.0%) 
WithoutCache: Ran 5512 iterations (341 outliers). 
WithoutCache: Rounded run time per iteration: 5.0802e-06 +/- 5.6e-09 (0.1%) 

ベンチマーク:

use Benchmark 'cmpthese'; 
use Mojolicious::Renderer; 
use Mojolicious::Controller; 
use Mojolicious::Plugin::Renderer::WithoutCache::Cache; 

my $controller   = Mojolicious::Controller->new; 
my $renderer_zero_keys = Mojolicious::Renderer->new; 
$renderer_zero_keys->cache->max_keys(0); 

my $renderer_nocache = Mojolicious::Renderer->new; 
$renderer_nocache->cache(Mojolicious::Plugin::Renderer::WithoutCache::Cache->new); 

cmpthese(
    -5, 
    { 
     'max_keys' => sub { 
      $renderer_zero_keys->render($controller, { text => 'foobar' }); 
     }, 
     'WithoutCache' => sub { 
      $renderer_nocache->render($controller, { text => 'foobar' }); 
     }, 
    } 
); 

__END__ 
       Rate  max_keys WithoutCache 
max_keys  190934/s   --   -2% 
WithoutCache 193846/s   2%   -- 

私はそれが最終的に違いを生むが、その考え通話の多い高負荷環境での偵察証明することは非常に難しいです。したがって、キャッシュの内部について考えるのが好きでない場合は、このプラグインが役に立ちます。


旧答え:Mojolicious::Plugin::EPRendererを見て

私はcacheがあることが分かりました。 getsetmax_keysのメソッドを持ち、Mojo::Base(おそらくMojoliciousのすべてのもの)から継承したMojo::Cacheインスタンスです。

::EPRenderer gets a $rendererは、Mojolicious::Rendererです。 Mojo :: Cacheインスタンスを保持します。私は$cData::Printerと見て、それらのすべてを保持する$c->appがあることを知りました。

これを知ることで、何もしない独自のキャッシュクラスを簡単に作成できます。

package Renderer::NoCache; 
use Mojo::Base -base; 

sub get {} 
sub set {} 
sub max_keys {} 

今度は$cに貼り付けます。

package Foo; 
use Mojolicious::Lite; 

get '/' => sub { 
    my $c = shift; 

    $c->app->renderer->cache(Renderer::NoCache->new); 

    $c->render(template => 'foo', name => 'World'); 
}; 

app->start; 

__DATA__ 

@@ foo.html.ep 
Hello <%= $name =%>. 

getまたはsetキャッシュへのあらゆる試みは、単に何もしません。それはキャッシングを試みますが、何も見つけられません。

もちろん、毎回新しいオブジェクトを作成するのは素晴らしいことではありません。起動時にそのオブジェクトを一度作成し、appの内部パーマネントバージョンにする方がよいでしょう。あなたはCGIを持っているので、違いはありません。


また、単にgetMojo::Cacheの外をサルは、パッチを当てることができました。これよりハックアプローチは同じことを行います。

package Foo; 
use Mojolicious::Lite; 

*Mojo::Cache::get = sub { }; 

get '/' => sub { 
    my $c = shift; 

    $c->render(template => 'foo', name => 'World'); 
}; 

app->start; 

しかしを注意してください:私たちはからモジョ::キャッシュを使用して、アプリケーション内のすべてのキャッシュをフェッチ無効。これはあなたが望むものではないかもしれません。

関連する問題