最近作ったN個のCPANモジュール Yokohama.pm #10

27
最近リリースした N個のCPANモジュール Yokohama.pm #10 2014/02/21 kazeburo

description

 

Transcript of 最近作ったN個のCPANモジュール Yokohama.pm #10

Page 1: 最近作ったN個のCPANモジュール Yokohama.pm #10

最近リリースしたN個のCPANモジュール

Yokohama.pm #10 2014/02/21

kazeburo

Page 2: 最近作ったN個のCPANモジュール Yokohama.pm #10

Time::Crontabparser for crontab date and time !eld

Page 3: 最近作ったN個のCPANモジュール Yokohama.pm #10

use Time::Crontab; my $time_cron = Time::Crontab->new('0 0 1 * *');if ( $time_cron->match(time()) ) { do_cron_job();}

Page 4: 最近作ったN個のCPANモジュール Yokohama.pm #10

[email protected] supports cron like job

Page 5: 最近作ったN個のCPANモジュール Yokohama.pm #10

use Proclet;my $proclet = Proclet->new();$proclet->service(...);$proclet->service(...);$proclet->service( code => sub { scheduled_work(); }, tag => 'cron', every => '0 12 * * *', #everyday at 12:00am);$proclet->run;

Page 6: 最近作ったN個のCPANモジュール Yokohama.pm #10

Apache::LogFormat::[email protected] bug!x around DST

@0.30 improvement strftime(2)

Page 7: 最近作ったN個のCPANモジュール Yokohama.pm #10

dex4er

Apache::LogFormat::Compiler has a problem. Twice a year the timezone is changed because of daylight saving. A::LF::C ignores this fact and still shows old timezone after change.

https://github.com/kazeburo/Apache-LogFormat-Compiler/pull/3

ALFC、DST(サマータイム)をサポートしてないよ!

Page 8: 最近作ったN個のCPANモジュール Yokohama.pm #10

version < 0.14local $ENV{TZ} = 'America/New_York';POSIX::tzset;my $time = timelocal(0, 0, 1, 3, 11 - 1, 2013);

my $log_handler = Apache::LogFormat::Compiler->new();my $req = req_to_psgi(GET "/");my $res = [200,[],[q!OK!]];

print $log_handler->log_line($req,$res,0,2,$time);print $log_handler->log_line($req,$res,0,2,$time+3599);print $log_handler->log_line($req,$res,0,2,$time+3600);__DATA__127.0.0.1 - - [03/Nov/2013:01:00:00 -0400] "GET / HTTP/1.1" 200 0 "-" "-"127.0.0.1 - - [03/Nov/2013:01:59:59 -0400] "GET / HTTP/1.1" 200 0 "-" "-"127.0.0.1 - - [03/Nov/2013:01:00:00 -0400] "GET / HTTP/1.1" 200 0 "-" "-"

時間が戻ってる!

Page 9: 最近作ったN個のCPANモジュール Yokohama.pm #10

version >= 0.14local $ENV{TZ} = 'America/New_York';POSIX::tzset;my $time = timelocal(0, 0, 1, 3, 11 - 1, 2013);

my $log_handler = Apache::LogFormat::Compiler->new();my $req = req_to_psgi(GET "/");my $res = [200,[],[q!OK!]];

print $log_handler->log_line($req,$res,0,2,$time);print $log_handler->log_line($req,$res,0,2,$time+3599);print $log_handler->log_line($req,$res,0,2,$time+3600);__DATA__127.0.0.1 - - [03/Nov/2013:01:00:00 -0400] "GET / HTTP/1.1" 200 0 "-" "-"127.0.0.1 - - [03/Nov/2013:01:59:59 -0400] "GET / HTTP/1.1" 200 0 "-" "-"127.0.0.1 - - [03/Nov/2013:01:00:00 -0500] "GET / HTTP/1.1" 200 0 "-" "-"

オフセットが変わった

Page 10: 最近作ったN個のCPANモジュール Yokohama.pm #10

dex4er

I'm trying to install Apache::LogFormat::Compiler on Android. This system has poor support for locales, so the Perl is usually compiled with -Ui_locale flag.

https://github.com/kazeburo/Apache-LogFormat-Compiler/pull/6

Andoroidがsetlocaleをサポートしてない!

Page 11: 最近作ったN個のCPANモジュール Yokohama.pm #10

$ export LC_ALL=ja_JP.UTF-8$ perl -MPOSIX=strftime \ -E 'say strftime(q!%d/%b/%Y%T!,localtime());'21/ 2月/2014:00:17:35

strftime(2) はlocaleによって出力が変わる

Page 12: 最近作ったN個のCPANモジュール Yokohama.pm #10

my $old_locale = POSIX::setlocale(&POSIX::LC_ALL);POSIX::setlocale(&POSIX::LC_ALL, 'C');$time = POSIX::strftime(‘%d/%b/%Y:%T’,localtime());POSIX::setlocale(&POSIX::LC_ALL, $old_locale);

ALFCはstrftime(2)の前にsetlocale(LC_ALL,C)してた%{format}t がstrftime(2) を使っていて、

Page 13: 最近作ったN個のCPANモジュール Yokohama.pm #10

       |   \  __  /   _ (m) _ピコーン      |ミ|    /  `´  \     ('A`)     ノヽノヽ       くく

そうだlocaleに影響を受けないstrftime(2)を作ろう

やめておけばよかった。。

Page 14: 最近作ったN個のCPANモジュール Yokohama.pm #10

POSIX::strftime::Compiler

Page 15: 最近作ったN個のCPANモジュール Yokohama.pm #10

$ export LC_ALL=ja_JP.UTF-8$ perl -MPOSIX::strftime::Compiler=strftime \ -E 'say strftime(q!%d/%b/%Y:%T!,localtime());'

21/Feb/2014:00:17:35

localeによって出力が変わらない! YATTA!!

Page 16: 最近作ったN個のCPANモジュール Yokohama.pm #10

Time::TZOffsetShow timezone offset strings like “+0900”

more portable than POSIX::strftime('%z') and fast

XSにてtm構造体のtm_gmtoffを取得するモジュールgmtoffをサポートしていないOSでは

localtimeとgmtimeの差分を計算

Page 17: 最近作ったN個のCPANモジュール Yokohama.pm #10

HTTP::Entity::ParserPSGI compliant HTTP Entity Parser

yet another HTTP::Body

based on tokuhirom's code. https://github.com/plack/Plack/pull/434

別のモジュールしてだれか進めて

Page 18: 最近作ったN個のCPANモジュール Yokohama.pm #10

use HTTP::Entity::Parser; my $parser = HTTP::Entity::Parser->new;$parser->register('application/x-www-form-urlencoded', 'HTTP::Entity::Parser::UrlEncoded');$parser->register('multipart/form-data', 'HTTP::Entity::Parser::MultiPart');$parser->register('application/json', 'HTTP::Entity::Parser::JSON'); sub app { my $env = shift; my ( $params, $uploads) = $parser->parse($env);}

Page 19: 最近作ったN個のCPANモジュール Yokohama.pm #10

WWW::Form::UrlEncodedparser and builder for application/x-www-form-urlencoded

Page 20: 最近作ったN個のCPANモジュール Yokohama.pm #10

s_id=1&type=foo&message1=foo+bar+baz+hoge+hoge+hoge+hoge+hogehogemessage2=

%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A7%E3%81%99%E3%82%88%E3%83%BC

(s_id => 1, type => 'foo', message1 => 'foo bar baz hoge hoge hoge hoge

hogehoge', message2 => '日本語ですよー')

parse build

Page 21: 最近作ったN個のCPANモジュール Yokohama.pm #10

'a=b&c=d' => ["a","b","c","d"]'a=b;c=d' => ["a","b","c","d"]'a=1&b=2;c=3' => ["a","1","b","2","c","3"]'a==b&c==d' => ["a","=b","c","=d"]'a=b& c=d' => ["a","b","c","d"]'a=b; c=d' => ["a","b","c","d"]'a=b; c =d' => ["a","b","c ","d"]'a=b;c= d ' => ["a","b","c"," d "]'a=b&+c=d' => ["a","b"," c","d"]'a=b&+c+=d' => ["a","b"," c ","d"]'a=b&c=+d+' => ["a","b","c"," d "]'a=b&%20c=d' => ["a","b"," c","d"]'a=b&%20c%20=d' => ["a","b"," c ","d"]'a=b&c=%20d%20' => ["a","b","c"," d "]'a&c=d' => ["a","","c","d"]'a=b&=d' => ["a","b","","d"]'a=b&=' => ["a","b","",""]'&' => ["","","",""]'=' => ["",""]'' => [] Plack::RequestやHTTP::Bodyとの

互換性を維持する

Page 22: 最近作ったN個のCPANモジュール Yokohama.pm #10

WWW::Form::UrlEncoded::XSXS implementation of parser and builder for application/x-www-form-urlencoded

Page 23: 最近作ったN個のCPANモジュール Yokohama.pm #10

Benchmark: running parse_pp, parse_xs for at least 3 CPU seconds...parse_pp: 3 wallclock secs ( 3.00 usr + 0.00 sys = 3.00 CPU) @ 27353.00/s (n=82059)parse_xs: 3 wallclock secs ( 3.02 usr + 0.00 sys = 3.02 CPU) @ 258802.32/s (n=781583)

Rate parse_p parse_xsparse_pp 27353/s -- -89%parse_xs 258802/s 846% --

parseのベンチマークで9.5倍高速

Page 24: 最近作ったN個のCPANモジュール Yokohama.pm #10

Benchmark: running build_pp, build_xs for at least 3 CPU seconds...build_pp: 4 wallclock secs ( 3.40 usr + 0.01 sys = 3.41 CPU) @ 15048.68/s (n=51316)build_xs: 4 wallclock secs ( 3.08 usr + 0.01 sys = 3.09 CPU) @ 651364.08/s (n=2012715)

Rate build_pp build_xsbuild_pp 15049/s -- -98%build_xs 651364/s 4228% --

buildは43倍高速

Page 25: 最近作ったN個のCPANモジュール Yokohama.pm #10

## content length => 38 ## Rate http_body http_entityhttp_body 35870/s -- -41%http_entity 60703/s 69% --

## content length => 177 ## Rate http_body http_entityhttp_body 14355/s -- -74%http_entity 54371/s 279% --

## content length => 1997 ## Rate http_body http_entityhttp_body 2054/s -- -92%http_entity 27049/s 1217% --

WWW::Form::UrlEncoded::XSをいれたHTTP::Entity::Parserのベンチマーク

Page 26: 最近作ったN個のCPANモジュール Yokohama.pm #10

これからの課題

• Plackに取り込んでもらう*Plackの依存モジュールは基本Pure Perl

• Plack::(?:Request|Response)の高速版を作る*互換性を保ちつつXS利用

Page 27: 最近作ったN個のCPANモジュール Yokohama.pm #10

いじょう。