ETagキャッシュによるポーリング
変更に対するポーリング(新しい変更があるかどうかを繰り返しサーバーに問い合わせること)は、GitLabインスタンスに高い負荷をもたらします。なぜなら、通常少なくともいくつかのSQLクエリを実行する必要があるからです。これは大規模なGitLabインスタンス(GitLab.comのような)のスケーリングを非常に難しくするので、ポーリングが必要でデータベースに負荷をかけるような新機能の追加は許可していません。
その代わりに、RedisでETagキャッシュを使ったポーリングメカニズムを使うべきです。
使い方
- ポーリングしたいエンドポイントのパスを
Gitlab::EtagCaching::Router
に追加します。 - レスポンスのポーリング間隔ヘッダーを
Gitlab::PollingInterval.set_header
で設定します。 -
Gitlab::EtagCaching::Store
を使って、エンドポイントのパスのキャッシュ無効化を実装します。リソースが変更されるたびに、このリソースに依存しているパスの ETag を無効にする必要があります。 - このメカニズムが動作することを確認してください:
- リクエストはステータスコード 304 を返すはずです。
- SQL クエリがログに記録されていません。
log/development.log
どのように動作するか
キャッシュ・ミス
キャッシュ・ヒット
- リソースが変更されるたびにランダムな値を生成し、Redisに保存します。
- クライアントがリクエストを行うと、
ETag
レスポンスヘッダに Redis の値を設定します。 - クライアントはレスポンスをキャッシュし(クライアントサイド・キャッシング)、同じリソースに対するそれ以降のリクエストで
If-None-Match
ヘッダとして ETag を送信します。 -
If-None-Match
ヘッダが Redis の現在の値と一致する場合、リソースが変更されていないことがわかるので、データベースにクエリすることなく、すぐに 304 レスポンスを送信することができます。クライアントのブラウザはキャッシュされたレスポンスを使用します。 -
If-None-Match
ヘッダが Redis の現在の値と一致しない場合は、リソースが変更されたため、新しいレスポンスを生成する必要があります。
ETag キャッシュを有効にしたいエンドポイントでは、クエリパラメータ (例えば?scope=all
) を使用しないでください。ミドルウェアはリクエストパスのみを考慮し、クエリパラメータは無視します。すべてのパラメータをリクエストパスに含める必要があります。こうすることで、クエリパラメータの並び順の問題を回避し、 ルートマッチを簡単にすることができます。
詳細は