ラベル Perl の投稿を表示しています。 すべての投稿を表示
ラベル Perl の投稿を表示しています。 すべての投稿を表示

2015/02/16

PSGI Server がリクエストボディをどうしているのか知りたくなったので…

背景

諸般の事情により(お察しください)、巨大なファイル(おおむね2GB以上)が HTTP で POST された場合に、PSGIでどのように処理されるのかを調べてみましたよ。
観点としては、PSGIより下のレイヤー(PSGI server)でリクエストボディをどのように扱っているのかを調査。全体をバッファリングしてしまうのか、またボディの読み込みを遅延(あるいは拒否)できるのかを確認した。

また、想定しているシステムの temp 領域がかなり小さいということもあって、PSGI app の中で HTTP ヘッダの内容にもとづいてボディの扱いを変えたい(指定したディスクにバッファリングするのか、それともそもそもボディを無視するのか)。そのため、バッファリングが遅延できるようになっていると嬉しい。

結論

総じていうと、 Stream::Buffered を使って事前にリクエストボディ全体をバッファリングしてしまう方法がスタンダード。(Starman から発祥し、Starletで固められたコードが決定版的な扱いになっている)

Stream::Buffered の挙動として、デフォルトでは 1MB まではメモリにバッファし、それ以上は tempfile に書き出してバッファリングするようになっている。($Stream::Buffered::MaxMemoryBufferSize で調整可能)

PSGI app が呼ばれる前にバッファリングされてしまうので、メモリかディスクにボディ全体が一度保存されるのは避けられない模様(´・ω・`)

以下、それぞれの実装の該当箇所への参照とメモ↓

Starman

このあたり↓

Plack::TempBuffer を使っているけど、現在 Plack::TempBuffer は Stream::Buffered のエイリアスになっているため上述の挙動となる。

Starlet

このあたり↓

Plack::TempBuffer を利用。Starman とだいたい同じ。

Monoceros

このあたり↓

Plack::TempBuffer を利用。Starman とだいたい同じ、というか Starlet のコードをそのまま使ってますね。

Stream::Buffered を利用。Stream::Buffered を使っている以外は、ほぼ Starlet のコードそのまま。 

Twiggy

このあたり↓

PerlIOを利用して、すべてオンメモリにバッファリングしている。
ちなみに、リクエストの chunked エンコーディングには対応していないようだ(´・ω・`)

Feersum

や、やばい…何やってるのか全然理解できない…
タンさんのコードが天才的すぎるのか…((((;゚Д゚))))

追記: AnyEvent::HTTPD

ついでに AnyEvent::HTTPD も読んでみた。このへん↓
https://metacpan.org/source/AnyEvent::HTTPD::HTTPConnection#L352

Content-length 分だけ丸っとメモリに読み込んでいますね。
ちなみに、chunked エンコーディングには対応していない様子。

他にも読むべき PSGI Server があったら教えてください><

2013/09/25

YAPC::Asia Tokyo 2013 に行ってきたので、Log::Minimal::Indent というモジュールを公開したという話


2年ぶりに YAPC::Asia Tokyo に参加してきました!

一時は参加も危ぶまれましたが、皆さまのお力添えもあって、無事に参加することができました。ありがとうございましたm(_ _)m

また、YAPCに関わっていたすべての皆様、お疲れ様でした><!

……というのが既に先週末で、時すでに水曜日というこの体たらくなわけですが、

というわけで、ブログ書きますよ><!

2011/10/14

YAPC::Asia 2011にやってきたので…

 今年もやって来ましたYAPC::Asia。
 まだ、一日目(前夜祭を入れると二日目?)の午前が終わったところなんだけど、KeynoteのJesse Vincentのトークを聴いて、Twitterで書き足りなかったところを書いとこうかと。

 実は、この話は事前にOSCON 2011のスライドを見ていたので知っていた。
 でも、実際にJesseのトークを直に聴くと、Perl5を良くしたい!という情熱がひしひしと伝わってくる。

 非常に大雑把に言ってしまうと、「Perl5をこれからも進化させ続けていくために、Perl5のコアを小さくしよう、過去の遺物を捨てられるようにしよう」、そういう方向に舵を切ったんだという話。
 でも、それをやりつつも、今動いているPerlプログラムは(可能な限り)動き続けるよう互換性を保つための提案をしている。
 とても野心的な話だ。(どんな方法を提案しているのかは、上のスライドを参照)

 個人的には、未来に向かって変わり続けようとする、この話には心から賛同している。
 一方で、この方向に舵を切ることで、Perl5が俺が大好きだったPerlではなくなってしまうのかもしれないなぁ…という一種の寂しさもよぎった。
 俺が大好きだったPerlというのは、つまり、なんでもござれの全部入りアーミーナイフなPerlのことだ。

 「Perlが使えれば、なんとかなる!」

 そんな妙な安心感をくれるPerlのことだ。

 一方で、コアを小さくして拡張はモジュールでやる方向性でいくと、その極限の解はSchemeだ。
 Schemeの世界は素直に綺麗だと思えるけど、俺の好きな世界ではなかった。
 やっぱり俺は、病的折衷主義者なのだね!

 Jesseはアーミーナイフともチェーンソーとも表現していたけど、Jesseもこのチェーンソーが好きみたいだ。
 だから、Schemeみたいになることはないと思う。
 そんなことをしても、嬉しい人は少ないと思うし。
 一方で、病的折衷主義と純粋主義とのバランスの狭間で、難しい舵取りをすることになると思う。

 色々思うところはあるけれど、前に向かって変わり続けるというのには大賛成だ。
 変わり続けることのみが、自分たちが自分たちで在り続けられるたった1つの方法だと思うから。

 今はただ、そんな大それた決断をしたJesseとPerl Mongerたちを、自分なりにサポートできる方法ってなんだろう、とそれを考えている。

2011/03/07

zshでperlbrewを補完するようにしたので…

 zshの補完ってホントに便利ですよねー
堕落しきった俺には、もはやperlbrewのサブコマンドを入力することさえ困難なのです。

 というわけで、perlbrewのzshでのコマンド補完(改) - LAPISLAZULI HILL#Hatena のルールを利用させてもらって、補完できるようにしました。

 でも、このルールは若干古くなっていたので、ちょこっと修正しまった↓
具体的には、switchとuseの補完候補にinstalledサブコマンド(listサブコマンドの古いやつ)を使うようになっていたので、修正しています。

 あとついでに、install候補も補完できるようにしときました。(※CPANからリストを取ってくるので、最初の補完には時間がかかりますが(>_<;)) これで、いちいちバージョンを調べなくても気軽にいろんなperlを試せますね!


 zshの補完関数はじめて書いたけど、こんなんでいいのかな?

3/11追記

 App-perlbrew-0.17にアップデートしたら、switch候補がちゃんと動かなくなったぽいので、修正しました。