FurlX::Coro を使ってみたかった
節電対応で休日が日・月になった hatyuki です。ということで、明日がおやすみ!
「DB から引っ張ってきた 5,000 件くらいの URL が、全部 HTTP Status Code 200 を返してくるか調べたいんだけど。」
という、なさそうでやっぱない依頼をうけたのでささっと書いてみることに。
ぱっと思いついたのはこんな感じ。
use strict; use warnings; use Furl; use My::Util qw/ db /; use Test::More; my $furl = Furl->new; my $itr = db->search('tables'); while (my $row = $itr->next) { my $res = $furl->head($row->url); is $res->code, 200, $row->url; } done_testing;
で実行してみたら Furl は確かに早いんだけど、さすがにチェックする URL の数が多すぎてちょっと時間かかりすぎる感じ。
そーいえば id:gfx さんが
- Released FurlX-Coro!
- http://d.hatena.ne.jp/gfx/20110625/1308978199
なんて記事を書いていたなぁ。と思い出したので FurlX::Coro を使ってみることに。
参照先の記事に書いてある内容そのままですが、こんな感じになりました。
use strict; use warnings; use Coro; use FurlX::Coro; use Test::More; use My::Util qw/ db /; my $itr = db->search('tables'); my @coros; while (my $row = $itr->next) { push @coros, async { my $furl = FurlX::Coro->new; my $res = $furl->head($row->url); is $res->code, 200, $row->url; }; } $_->joins for @coros; done_testing;
Furl の代わりに Coro と FurlX::Coro を use して、あとは Coro っぽい書き方をちょっと加えるだけなので、すごく簡単ですね。
で、実行してみたら超はや、、、あれ?
「おい!Load Average が 300 超えてるぞ!」
あー。そういえば URL って全部同一ドメインだった!
ということで Coro::Semaphore も使うことに。
こんな感じ。
use strict; use warnings; use Coro; use Coro::Semaphore; use FurlX::Coro; use Test::More; use My::Util qw/ db /; my $itr = db->search('tables'); my @coros; my $semaphore = Coro::Semaphore->new(10); # 10 並列まで while (my $row = $itr->next) { push @coros, async { my $guard = $semaphore->guard; my $furl = FurlX::Coro->new; my $res = $furl->head($row->url); is $res->code, 200, $row->url; }; } $_->joins for @coros; done_testing;
今度こそ、早く安全 (?) に HTTP Status Code を確認することができました。
やったね!
えっ?確認すべき URL があと 100,000 あるの?なんか間違ってない。。。?
そんな週末。
perlbrew 環境下で Alien::SVN をインストールする
どうしても Perl *1 から Subversion を操作する必要があったので、どうやら一般的なモジュールのようなので、以下のモジュールを使ってみることに。
と思ったら perlbrew 環境下ではすんなり cpanm できなかったのでメモ。
Debian というか、パッケージシステムの問題 (?) というか。
Debian は Testing な wheezy。
Subversion はいつもどおり aptitutde でインストール。
# aptitude install subversion
これで libsvn-perl も同時にインストールされるため、システムの Perl を使っている分には別途で Alien::SVN をインストールする必要はないみたい。
今回は perlbrew 環境下で、システムにインストールされている Perl とは違うバージョンを使っていたため、cpanm することに。
ただし、単純に
$ cpanm -l extlib Alien::SVN
すると、apr / apr-util / neon *2 がないよ!と言われて make に失敗するので
# aptitude install libapr1-dev libaprutil1-dev libneon27-gnutls-dev
すれば、インストールできるようになりましたとさ。
やったね。
Alien::SVN の使い方は、またの機会に。
「いまさら Subversion ?」は、なしだよ!
Ark + DBIx::Skinny + Text::Xslate (+Tiffany) で NoPaste 的な何か
Shibuya.pm #14 にいってきました
今回のテーマは「IPAとJPAは違う団体です」ということで、IPA と JPA の両者が参加。
ということで、いつも通りてきとうなまとめ。
Perl 6 Language Update (dankogai さん)
- 大まかには Perl6 も Perl5 もあんまり変わらないよ
- 構文とかだいぶ違うようにみえるけど。。。
- "Rakudo Star" がリリースされたけど、今はまだだいぶ遅い
- 単純なスクリプトでも 5 と 6 では大きな差がある
- それでも昔よりはだいぶ早くなった
- sub の中に sub (Private Function) がかけるようになった。
sub fizzbuzz { sub fizz { }; sub baz { }; }
- try - catch が使えるようになる
- まぁ、前から eval { }; if ($@) { } があったけどね
- "try" の中に "CATCH" があるんだけど
- どうしてこうなった
- 変数のスコープ考えるとこっちのが便利じゃない?(会場内の Twitter から)
try { die; CATCH { say $@; } }
ぼくのかんがえたさいきょうのYAPC::Asia (941 さん)
- チケットかってね!
memcached injection (佐名木 さん)
- 最近某 SNS の memcached に障害が発生して話題になった
- 今回はその件とは別
- memcached は非常に簡単なテキストベースのプロトコル
- 基本的には、Key と Value をテキストで送信して Store しているだけ
- キー名のエスケープは memcache 側ではやっていない
- Server / Client 側でサニタイズ処理をしてあげる必要がある
- 各言語のライブラリによって、サニタイズ処理をしている場合と、していない場合がある
- とはいえ、キーの値がユーザが指定した任意の値になるようなアプリは少ないはず
- キーに対する Injection といえば SQL Injection
- Colum に Injection できるというものが過去にあった。が非常に稀なケース
SELECT * FROM table WHERE column = 'hoge'; -- ↑ ここが、ユーザが任意で指定できちゃうようなアプリ
- memcached を使った攻撃方法があるって書いたら中国から大きな反響があった
- どうやら攻撃が好きみたい
- 攻撃されないようにね!
memcached の運用監視ノウハウ (kazeburo さん)
- mixi で memcached 周りの障害が発生したことを Twitter で報告した
- 大きな反響があり、多くの方に原因究明をしていただいた
- それはそれでいいことだと思った
- 障害から分かったことは memcached を安定稼動させることの重要性
- 安定稼動とは PDCA サイクルである
- 監視とは継続的なテストである
- 継続的にテストするためには
- 自動化しようね
- 可視化しようね
- 継続的にテストするためには
- どうやって監視していく?
- 直近に実行したコマンドの終了ステータスを監視する
$ COMMAND $ echo $? 0 <- COMMAND の終了ステータス
-
- cronlog 使うと非0の場合のみに STDOUT / STDERR を出力してくれるので便利
- cronlog は github の kazuho さんのとこで!
- netcat (nc コマンド) も便利だよ
- crontab に仕掛けるコマンドを以下のようにする
- cronlog 使うと非0の場合のみに STDOUT / STDERR を出力してくれるので便利
cronlog -- nc -w 1 -z localhost 11211 # nc の終了ステータスが 0 以外のときにメールがくる
-
- コマンドに対する応答が返ってくるかを監視する
- Nagios の Plugin 化してしまう
- status を使ってコネクション数を監視する
- daemontools とか使ってると障害を検出できないかもしれないよね
- supervisor によって再起動されるため、監視と監視の間に障害が発生すると補足できない
- uptime を使ってみてはどうか
- コマンドに対する応答が返ってくるかを監視する
身につけておきたい、今そこにあるシステムの救命措置 (IPA 園田 さん)
- 脆弱性の報告は順調に増えている (良いことなのか、悪いことなのか)
- DNS特需とかあって、急激なグラフの部分もあるけどね
- 90日以上の長期化案件がけっこうある
- 1年放置とかザラ
- 1000日以上脆弱性が放置されているパターンもある
- どうすんのこれ?を今考えてたりする
- 稼働中のシステムの脆弱性の大半はエスケープのミス忘れたとかそんなもん。なのになんで直らない?
- いっそのこと「脆弱なサイトはこちらでーす」と公開してしまいたいくらい
- 下手するとデスマーチを強いるし業務妨害じゃん
- 現場的にはどんなプロセスなら現実的なの?
- ネックなのは予算?技術?体制?顧客の理解?
- 以下パネルディスカッション
- 941 さんのすばらしいまとめ -> http://togetter.com/li/55216
- Twitter の脆弱性もどんどん悪質化した
- 公開してしまうと本気で攻撃しちゃう
- IPA から報告をいれたくても報告先にたどり着くのにえらい時間がかかる場合がある
Perl 1,2,3,4 の歴史 (前田 さん)
- Perl1 〜 Perl5 までの歴史
- Tokyo.pm の大きな功績は miyagawa さんに Shibuya.pm を作らせたこと
Data::MessagePack (tokuhirom さん)
String::Filter 構造化テキストの正しいエスケープについて (kazuho さん)
Perl Parser Hacks vol.2 (gfx さん)
さいごに
今回も「偶然」出張だったので参加してきました!
うん、偶然。
というわけで、懇親会とかには参加できなかったのですが楽しかったです。
脆弱性あたりの話は難しそうですね。脆弱性の指摘があったときに、すぐに立ち回れる企業と、そうでない企業とありそうですし。
# Twitter にもでてたけれど、外部業者にお願いしていた場合とか
そう考えると、自分のとこもすばやく立ち回れるんだろうか。。。といった疑問も。
そういった意味でも kazuho さんのバグがあってもいいから、セキュアなコードを書くというのは、本当に意識していかなければいけないなぁと思います。
それでも見つかってしまう脆弱性については、すばやく対応することが大切ですよね!
Template Engine がその辺はよしなにしてくれるから!と知っていても、脆弱性についてきちんと理解しておくことも大切ですね。
Xslate に入門しつつ Tiffany とか Ark とか
最近はもっぱら PHP を書いている magicalhat です。
それでもやっぱり Perl が好き。
というわけで、id:gfx さんの新作 Xslate という新しいテンプレートエンジンが登場したとか、それがすごく速いとか、そんなウワサを耳にしたので入門してみることに。
ついでなので、最近鋭意お勉強中の Ark から Xslate を使ってみることにしました。
参考にしたのは、id:punitan さんが Blog で紹介されていた http://xslate.org/intro.html のサンプルプログラムです。
# いつものことですが、参考というよりもパクりです
Ark::View::Xslate をつくってみる
Ark が標準でサポートしているのは JSON / MT (Text::MicroTemplate::Extended) / TT (Template-Toolkit) のみなので、新しく Ark::View::Xslate をつくってみることに。
といっても、既存の Ark::View::MT をそのままコピーペして。。。
↓こんなかんじで完成。
Ark からつかってみる
作成した Ark::View::Xslate を使って http://xslate.org/intro.html のサンプルと同じ出力を得るための Ark のアプリケーションはこんな (↓) かんじに*1。
- Ark から Xslate してみる版
- http://github.com/magicalhat/p5-axtest/tree/xslate
いまどき Controller にロジックを書くひとって。。。
なんかスマートじゃないよね。。。
何も考えずに Ark::View::MT を参考にコピペしてしまったので、なんか設定項目がたくさんあってスマートじゃないよねぇ。とか考えていたら
http://twitter.com/__gfx__/status/20446194779
http://twitter.com/__gfx__/status/20446202825
まったくもってその通りですね!
というわけで、options だけを残して。。。
と思っていたら、id:tokuhirom さんのこの記事が。
Tiffany をつかってみる
ちょうどいいタイミングだし使ってみよう。
というわけで、今度は Ark::View::Tiffany を作ってみました。
↓こんなかんじ
この機会にちょっと Ark のソースコードを追いかけてみたりもしました。
が、それはまたの機会に。
Tiffany から Xslate / MT してみる
Tiffany は決して Template Engine を切り替えるものではない*2ので、使い方としては間違っている気がしますが、とりあえず Tiffany の機能を堪能するために、MT と Xslate が同じ View クラス (Ark::View::Tiffany) から利用できることを確認してみることに。
こんなかんじ↓ *3
- Ark から Tiffany 経由で Xslate / MT してみる版
- http://github.com/magicalhat/p5-axtest/tree/tiffany
Tiffany を使うことによるメリットは、WAF ごとにいちいち WAF::View::TemplateEngine を作成しなくても、いろんな Template Engine を利用できることですね。
実際に、今回の例だと Ark::View::Xslate を作らずに Xslate に対応することができ、また Ark::View::MT を利用することなく、MT の Template Engine を利用することができました。
Ark(::View::Tiffany) を使う場合は以下のように設定をすれば、(Tiffany が対応している) 好きな Template Engine を利用できます。
たぶん TT とかでも使えるとおもうけど、確認はしてないです。
MyApp.pm
package MyApp; use Ark; our $VERSION = '0.01'; use_model 'MyApp::Models'; my $home = MyApp::Models->get('home'); # Xslate を使う場合 config 'View::Tiffany' => { view => 'Text::Xslate', extension => '.tx', options => { path => $home->subdir('root', 'tmpl'), cache_dir => $home->subdir('tmp', 'xslate_cache'), }, }; # MT を使う場合はこっちを有効に #config 'View::Tiffany' => { # view => 'Text::MicroTemplate::Extended', # options => { # include_path => [ $home->subdir('root', 'tmpl') ], # template_args => { # stash => sub { __PACKAGE__->context->stash }, # }, # }, #}; 1;
MyApp::View
View 側は Tiffany がよしなにしてくれるので、名前を確保するだけ。
うん。スッキリ。
package MyApp::View; use Ark 'View::Tiffany'; 1;
完成?
とりあえずは完成したっぽいけれど、Ark::View::MT には、Form の Action がある場合には HTML をエスケープせずに、そのまま出力するように特殊な処理が入っており、この辺の Template Engine 固有の処理を、どうやって対処するのが適切なのかは考えどころかな?
などなどと思っています。
で、速いの?
むずかしいことはよくわかりませんがすごくはやいみたいです><
PerlCasual#02 へいってきました
Twitter では訳あって hatyuki に改名した magicalhat です。
懲りずにまた遠方から参加させていただきましたので、超簡単にメモ。
てゆーか殴り書きれべるだけど。
オープニング
Perl の真価は CPAN !
っていうけれど、それをモジュール数ではなく、Autor として考えることに感動。
Perl の「コミュニティ」がすごいっていうのは、そういった人の繋がりが大きいからということですね。
Live Coding
- Perlism っぽいものを作ってみよう
- CPAN フル活用ですばやくいろいろ作れるよ
- ドキュメントは perldoc で!
$ perldoc Module::Name $ perldoc -f function_name (←Perl の組み込み関数のヘルプ)
-
- SYNOPSIS を見れば使い方は一通り分かるね!
ぷりんとでばっぐさいきょー。
LL
Emacs
- モード切替がない分 vim より変態じゃない
- anything.el という革命児 (インタフェース) を使うことでハッピーなプログラミングを
perlbrew
懇親会
知らない人だらけでした><
ご挨拶できなかった方もいましたが、いろいろな方とお話することができました。
やっぱ少し輪に入りづらい部分もあるんですが。。。(性格的な意味で)
なんか Perl バリバリな方ばかりかとも思いましたが「メインは PHP なんですよ」という方も多く、本当にカジュアルに楽しめました。
Web に目がいきがちだけれど、やっぱり簡単なツールとしての需要も高いんだなぁ。
と、お話をしている中でも実感しました。
これから Perl を覚えたい!という方にはちょっと敷居が高かったのかもしれませんが、懇親会で親しくなれればすぐに覚えられそうですね><
なくらい、すごく人に恵まれた言語ですね。
bless { relationship => $humans }, 'Perl';
な感じ?
まとめ
もうこうなったら「とーいところから来る人」と言われるよう、継続的に参加していきたいです。
あと、hide-k さんのあばら骨の行方がひっそりと心配でした。
DBIx::Skinny で update_or_create
ができたらいいなー。
と思ったので、作ってみました。
- DBIx-Skinny-Mixin-UpdateOrCreate
- http://github.com/magicalhat/p5-dbix-skinny-update_or_create
DBIx::Class だと、利用することも多いので Skinny でもあれば便利かな?と思ってみたり。
オマケとして、UPDATE じゃなくて INSERT した場合には、関連するレコードも更新しなくちゃ!
とゆーパターンも想定して、DBIx::Class でも利用できる in_storage というメソッドもつけてみました。
my $row = Proj::Model->update_or_create( table_name => { id => 1} => { name => 'magicalhat'} ); # -- insert したならば、別の処理をする unless (Proj::Model->in_storage) { my $reg = Proj::Model->create( register_table => { registered_id => $row->id} ); }
とりあえず、自分が使う分にはべんり!
Mixin 簡単に作れて面白いですね。これからもなんか気づいたら作ってみよー。