2009/10/05


spiritlooseさんがPSGIなapacheモジュールを書いてくれたのでWindowsにポーティングしてみた。
mod_psgi を実装してみた - spiritlooseのはてなダイアリー

PSGI を実装したApache2モジュール。

http://d.hatena.ne.jp/spiritloose/20091002/1254467284
ちょっと気持ち悪いpatchになるけど、一応動いている。
巷にあるライブラリなどではWindowsポーティングされた時にUN*Xライクな型を自前で定義している事があるんだけど、Apacheモジュールのapr.hなんかや、Perlなんかでuid_t/gid_t/pid_tなんかが定義されている事が多い。

apr.h
typedef int uid_t;

perl.h
typedef long uid_t;

もちろんこのヘッダを同時に読み込むとエラーになるんですが、こういう場合に私がよく使う手として
#define uid_t _uid_t
#include <apr.h>
#undef uid_t
#include <perl.h>
てな具合に前の宣言を逃してやって、後の宣言を有効に出来る。今回はこの気持ち悪いhackを使ってWindowsにポーティングしました。

Commit 03fb93ebf27f0b98c3fbcc616ce736129e747912 to mattn's mod_psgi - GitHub
http://github.com/mattn/mod_psgi/commit/03fb93ebf27f0b98c3fbcc616ce736129e747912
今の所ご機嫌よく動いていて use strict;
use warnings;
my $count = 0;
my $handler = sub {
    my $content = "Hello World".$count++;
    return [ 200, [ "Content-Type" => "text/plain", "Content-Length" => length($content) ], [ $content ] ];
};
# vim:set ft=perl:
こんなPSGIなアプリもうまくちゃんとリクエスト毎にカウントアップされています。
もちろんpreforkだと同じ結果が現れる事がありますが
まだマージして頂いていないので、捨てコードになるかもしれませんが...

AWSWORD:perl:
Posted at by



2009/10/02


tthttpd(tinytinyhttpd)にiratqqさんがIPv6対応をコードを入れてくれました。通常起動でIPv4、IPv6どちらも扱える様になっていて、引数で # tthttpd -4
とすればIPv4だけで # tthttpd -6
とすればIPv6だけで起動する様になります。iratqq++
また、静的なファイルをサーブする場合にはこれまでreadしながらsendしていたのですが、sendfile(2)を使う様にしました。Windowsの場合は昨日Plackの高速化対応した時の様にTransmitFileを使うようにしました。
小さいサイズのファイルだと差は出ませんが、数メガくらいのファイルから格段に差が出て速くなりました。
mattn's tinytinyhttpd at master - GitHub

tiny tiny httpd

http://github.com/mattn/tinytinyhttpd

Posted at by




最近熱いPSGI/Packですが、サーバのStandaloneではかなり高速なパフォーマンスが出ているらしく、試してみようと思った所、Windowsでは動かない箇所があったのでいろいろやった作業履歴。
まず、Standaloneサーバが速いと言われる理由としてsendfile(2)を使っているのですが、Windowsにはsendfile(2)がありません。しかしソケット前提であるならばTransmitFileというAPIがあります。
sendfile(2)と同じようにZeroCopyでファイルから指定ディスクリプタに流し込むAPIです。
Plackが使っているSys::Sendfileに対してこのAPIを使う様にWindowsポーティングしました。
Sys::Sendfileのauthorにもpull requestを送りました。次にPlackにてWindowsで使えないAPIを叩いている部分に対するpatchを書きました。
これで一応、高速化対応は完了。
Plackに付属の画像を返すpsgiアプリケーションを起動してベンチマークを取ってみました。
# plackup -s Standalone -a eg/dot-psgi/image.psgi
ベンチマーク結果は以下の通り。まず高速化対応前。
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient).....done


Server Software:        Plack-Server-Standalone/0.01
Server Hostname:        localhost
Server Port:            8080

Document Path:          /
Document Length:        2397678 bytes

Concurrency Level:      1
Time taken for tests:   1.219 seconds
Complete requests:      10
Failed requests:        0
Write errors:           0
Total transferred:      23978730 bytes
HTML transferred:       23976780 bytes
Requests per second:    8.21 [#/sec] (mean)
Time per request:       121.876 [ms] (mean)
Time per request:       121.876 [ms] (mean, across all concurrent requests)
Transfer rate:          19213.49 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   4.9      0      16
Processing:   109  119  10.9    125     141
Waiting:        0    5   7.5      0      16
Total:        109  120  12.9    125     141

Percentage of the requests served within a certain time (ms)
  50%    125
  66%    125
  75%    125
  80%    141
  90%    141
  95%    141
  98%    141
  99%    141
 100%    141 (longest request)
そして対応後 This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient).....done


Server Software:        Plack-Server-Standalone/0.01
Server Hostname:        localhost
Server Port:            8080

Document Path:          /
Document Length:        2397701 bytes

Concurrency Level:      1
Time taken for tests:   0.578 seconds
Complete requests:      10
Failed requests:        0
Write errors:           0
Total transferred:      23978960 bytes
HTML transferred:       23977010 bytes
Requests per second:    17.30 [#/sec] (mean)
Time per request:       57.813 [ms] (mean)
Time per request:       57.813 [ms] (mean, across all concurrent requests)
Transfer rate:          40504.51 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3   6.6      0      16
Processing:    31   55  22.4     47      94
Waiting:        0    3   6.6      0      16
Total:         31   58  24.5     47     109

Percentage of the requests served within a certain time (ms)
  50%     47
  66%     47
  75%     63
  80%     94
  90%    109
  95%    109
  98%    109
  99%    109
 100%    109 (longest request)
だいたいRequests perl secondで2倍くらい速くなってます。すばらしい。

miyagawa++ kazuho++ Plack++
Posted at by