Kawababa

始まり

5/10です。

今日やったこと

キャッシュを返却するように実装

めちゃくちゃ時間がかかったけど、実装完了。
長かったので、さらに分割して説明していく。

キャッシュチェックのプログラムどうやって作るんだ問題

昨日言っていた問題点である、RewriteとModifyResponse間での状態共有については、ミドルウェアで解決しそうであることがわかった。
しかし気になったのは、いつミドルウェアたちは実行されて、いつRewriteやModifyResponseは実行されるのかということ。
なので、goのコードをクローンしてきて、少し読んでみることにした。

調査開始

まずServer.ListenAndServe()が呼ばれると、tcpのコネクション待受状態に入る。
次にサーバはServer.Serve()を呼び出す。
Server.Serve()ではTCPのコネクションを確立すると、httpパッケージのローカル構造体であるconnを生成し、 conn.serve()を呼び出す。
conn.serve()では、conn.serverserverHandlerとしてキャストし、そのままserverHandlerServeHTTPを実行する。
conn.serverListenAndServeメソッドを実行するときに作成したものだ。
RewriteReverseProxyServeHTTPメソッド内で実行されるため、結局のところ、ReverseProxyもミドルウェア的なものでしかないわけだ。
しかもミドルウェアということは、登録の順番を制御すれば、実行の順番も管理できるので、ハッシュ管理ミドルウェアの後にリバースプロキシが実行されるようにすれば良さそう。

実装

今回実装するミドルウェアはcheckCache。 checkCacheは受け取ったリクエストに含まれる情報から、キャッシュキーを生成してキャッシュに存在するかどうかチェックを行う。
存在すれば、それを直接クライアントに返却し、存在しなければオリジンサーバにリクエストを飛ばすために、リバースプロキシに処理を任せると言った具合。

なんだかんだエラーが色々出たり、LRUCacheに問題が見つかったりしたので、それらを修正し完成。

画像だと分かりにくいかもしれないが、同じcurlコマンドを二回打った結果だ。
一回目はキャッシュがないので、Cache MISSとログに出力されており、その後のModifyResponseのタイミングで、キャッシュが新しく登録されている。(Add ... to cacheの行)
二回目はキャッシュがあるので、Cache HITとログに出力されており、オリジンサーバへのリクエストなしで、保存されたキャッシュが返却されていることが確認できる。

実装自体は、そこまで難しいものではなかったが、ライブラリの仕組みを知るのに時間がかかってしまった。

終わり

今日は、結構タフな仕事をしたのに、ブログも同じ日に書いているので、疲れた。
明日からは、キャッシュ機能は実装できたので、機能の追加をしていくイメージかな。
Consistent Hashingまではなんとか辿り着きたい。それと、今のうちにテストコードを増やしておきたい。

やりたいことリスト