Fukuoka Perl Workshop #20

基本情報

項目 内容
*日程 11月26日 (土) 14:00〜18:30
*主催 Fukuoka.pm
*会場 株式会社ヌーラボ
*公式サイト http://fukuoka.pm.org/2011/11/fukuoka-perl-workshop-20.html
*ハッシュタグ #fukuokapm

全体の印象

前日は、大分でコアラナイトと飲み会で結局、大分泊。朝、福岡に帰ってきて参加というちょっとした強行軍

内容はYAPC::Asia Tokyoというイベントが10月に開催されていたようで、その報告会も兼ねていた様子。
YAPC::Asiaの何がすごいって、基本的な講演内容で、終了後にアップデートされて動画なんかが追加されてる。
こういう細やかな運営ってのは簡単なようでいてすごいなぁっと思う。ので、関連しそうなセッションのURLもつけておく

・大学時代はPerlがメインだったけど、会社ではPHP
・最近触れてないので、最近の状況はちんぷんかんぷん
・やっぱり久しぶりにPerlを触るのもいいなぁっと思った一日でした
・fukuoka.pm自体は2003年頃からやっているらしい

次第

・[2011-12-06-5]
・[2011-12-06-4]
・[2011-12-06-3]
・[2011-12-06-2]
・[2011-12-06-1]

関連サイト

YAPC::Asiaのタイムテーブル(各セッションの動画あり)

YAPC::Asia Tokyo 2011 Timetable
「LT Day 1」の詳細 – YAPC::Asia Tokyo 2011
「LT Day 2」の詳細 – YAPC::Asia Tokyo 2011

YAPC

会場
: 株式会社ヌーラボ

登壇者: @kiwanami

まとめ
: [2011-12-06-6]

YAPC::ASIAについて

・おもてなしのある会
・参加者層も幅広く、初心者からまで幅広い感じ
 ・既に広く使われているPerlの余裕、大人感の感じられる会
・LTが特に面白かった

@kiwanami的に注目していたのはUIと非同期だった様子

Webアプリケーションの高速化

MemCatcheはCPU負荷が高すぎるという認識

・Bloom Filterとキャッシュ
・User Action Warmup、ユーザのアクションを先読みしてキャッシュを生成する
・Complicated Reverse Proxy

多分このセッション。「Webアプリケーション高速化」の詳細 – YAPC::Asia Tokyo 2011

Perlでモナド

・これから発展しそうな分野

多分このセッション。「Monads in Perl」の詳細 – YAPC::Asia Tokyo 2011

個人的に

実はモナドってよくわかってない

AnyEvent, Coro, IO::AIO – a good team

多分このセッション。「AnyEvent, Coro, IO::AIO – a good team」の詳細 – YAPC::Asia Tokyo 2011

個人的に

AnyEventがよく分からなかったけど、要はイベントを管理するためのライブラリっぽい
ただ、Perlの人達的にはかなり当たり前な技術になっているようなので、後で確認したい。
わからないことだらけ
[Perl Hackers Hub:第2回 AnyEventでイベント駆動プログラミング (1)|gihyo.jp … 技術評論社](http://gihyo.jp/dev/serial/01/perl-hackers-hub/000201)

Mobage

2 Access Interface。
データに対して、複数のアクセス手段を準備すると捗るという話。
例えば基幹となりそうなシステムを切り替えるときも片方のアクセス手段を残しつつ、もう片方をリリースすると
万が一、ポシャったときにもリカバリがやりやすい的な話だった気がする

・DNS、Mysql
・Mysql、HS Protocol

多分このセッション。「Mobageソーシャルゲームにおける大規模サーバ運用 with Perl」の詳細 – YAPC::Asia Tokyo 2011

その他の話題

運用と開発(DevOps、Develop, Operations)

最近流行りの話しらしい
[開発と運用の新しい関係、「DevOps」とは何か?](http://www.publickey1.jp/blog/11/devops.html)

YAPC

会場
: 株式会社ヌーラボ

登壇者: @debility

まとめ
: [2011-12-06-6]

・AnyEventは普通に使われている
・DevOps
・「ぼくのかんがえたさいきょうの~」が流行ってた

面白かったセッション

Webアプリケーション高速化
Perlで構築された中規模サイトのDC引っ越し記録
大規模環境における、マニアックなキャッシュ利用術
Perlで無理ゲーム攻略
闇のEメール伝説

面白かったLT

・@kawanami 氏, perl Emacs And Async
・@nitro_idiot 氏, Perl → Common Lisp
・ガイアックス, スポンサードセッション
http://yapcasia.org/2011/talk/98 の上から3つ

その他の話題

・画像のキャッシュ
・Webアプリのパスワード保護

その他みんなでがやがやと1 – Fukuoka Perl Workshop #20

会場
: 株式会社ヌーラボ

まとめ
: [2011-12-06-6]

いろんなモノがあるけど、どれを使ってる?

ORマッピングの話

Perlで何を使うか?
・DBI?Teng?
・ResultセットがないDBI::C?

色いろあるよ
・DBI
・CDB (使わないよ)
・DBC (使わないよ)
・DBIx
・DBIx::Skinny
・Teng

フレームワークの話

・Amon2
・Catalyst
・Mojolicious
・Dancer

テンプレートエンジン

・TT
・Xslate
・EmbedPerl

フロントエンド

・Apache
・nginx
・Cherokee
・Miytd

Web フレームワークに必要な機能

・ルーティング
・ディスパッチ
・テンプレート
・入力バリデーション
・パラメータのパース

※ あと一個くらいあった気がするけどメモれてなかった

これがどこまで必要か?結局はフルスタックで必要か?

その他の話題

SQLのViewは使うべき。

その他みんなでがやがやと2 – Fukuoka Perl Workshop #20

会場
: 株式会社ヌーラボ

まとめ
: [2011-12-06-6]

YAPC::Asiaで興味のある話題

・フレームワークの話
 ・Dancer(RubyのSinatraみたいな感じ)

・地方の話が面白い
 ・福岡から参加した人が多く、福岡押しだった
 ・福岡は、コミュニティー間の横の繋がりが多い
  ・Perlの人がRubyのコミュニティーに。その逆も
 ・北海道も多かった
 ・地方のLT枠が面白かった

・変なCPANの紹介

・Perlはインフラに寄ってきた
 ・若い人はPython、Rubyに行く
 ・Perlの人は、そろそろマネージャになってきてるかも

PerlでHadoopのMap-Reduceを書く

Hadoop Streaming – naoyaのはてなダイアリー

最初Rubyで書いたけど、なれないことで悩みたくなかったのでとりあえずPerlで
例示は、ありがちな「単語の数を数える」

サンプル

処理対象のデータ

$ cat data

aaa bbb ccc ddd
eee fff ggg hhh
aaa bbb ccc ddd

プログラム

$ cat mapper.pl

#!/usr/bin/env perl
# mapper.pl
use strict;
use warnings;
while (<>) {
chomp;
my @fields = split /[\s\r\n]+/;
foreach my $word ( @fields ) {
printf "%s\t%s\n", $word, 1;
}
}

$ cat reducer.pl

#!/usr/bin/env perl
# reducer.pl
use strict;
use warnings;
while (<>) {
chomp;
my @fields = split /[\s\r\n]+/;
foreach my $word ( @fields ) {
printf "%s\t%s\n", $word, 1;
}
}

面倒なので実行用のShellスクリプト

$ cat doHadoop.sh
#!/bin/sh

# 結果のディレクトリを初期化する
echo "upload data file"
hadoop dfs -put $1 $1
echo "delete output dir"
hadoop dfs -rmr $2
echo "start hadoop"
time hadoop jar /usr/local/hadoop/contrib/streaming/hadoop-streaming-0.20.203.0.jar -input $1 -output $2 -mapper $3 -reducer $4
hadoop dfs -get $2/part-00000 part-00000

動かしてみる

$ ./doHadoop.sh data out /path/to/mapper.pl /path/to/reducer.pl
$ cat part-00000
eee 1
hhh 1
ggg 1
bbb 2
fff 1
aaa 2
ccc 2
ddd 2

※ mapperとreducerはフルパスで書かないと怒られるっぽい

phpの中からPerlのプログラムを記述して実行する

いったいなぜこう言うことになったのか、色々と混ぜるな危険な感じですがとりあえず。
まだ、簡単なプログラムでしか試してないので色々とエスケープとか足りてない気がするし、ステータスコードをみて強制終了するのではなくちゃんと結果を返したほうがいいような気がするし、まぁ緊急避難的な対応ということで

|php|
/*
* Perlで文字列を取得する
*
* @param string $str
* @return array string :
/
function perlprint($string) {
$tokens = array();

  // 状況に応じてエスケープする必要があるけど、今回は面倒なので消した
$string = preg_replace("/[\$@%]/", "", $string);
// このヒアドキュメントの中に実行するPerlのプログラムを記述する
$script = <<<EOF
use utf8;
use strict;
use warnings;
use encoding 'utf8';
## Perl側の変数はエスケープして\$にしておく
## PHP側の変数は特にエスケープせずに記述
## ヒアドキュメントもかけちゃうよ
my \$str = <<STR;
$string

STR

    print \$str;

EOF;

  $ret = $this->execPerl($script);
return($ret);
}
/**
* 与えられたスクリプトをPerlで実行する
*
* @param string $script
* @return mixed  :
*/
function execPerl($script) {
// エスケープしていたPerl側の変数をもとに戻す
$script = preg_replace("/\\\$/", "$", $script);
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w"),
);
$cmd = "/usr/bin/perl ";
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
// $pipes はこの時点で次のような形を取っています。
// 0 => 子プロセスの stdin に繋がれた書き込み可能なハンドル
// 1 => 子プロセスの stdout に繋がれた読み込み可能なハンドル
// 2 => 子プロセスの stderr に繋がれた読み込み可能なハンドル
fwrite($pipes[0], $script);
fclose($pipes[0]);
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
// デッドロックを避けるため、proc_close を呼ぶ前に
// すべてのパイプを閉じることが重要です。
fclose($pipes[1]);
fclose($pipes[2]);
$return_value = proc_close($process);
}
# コマンドの返り値が0以外なら標準エラー出力をそのまま返して終了
if( $return_value != 0) {
die("perl error: {$return_value} \n{$stderr}");
}
return ( array("stdout" => $stdout, "strerr" => $stderr) );
}

||<

更新Pingを発行できるように修正する

先日、このブログがGoogleのブログ検索で引っかからないとぼやいたところ、藤野 氏より「いや、更新pingが打てないのはブログじゃないよね」的なごく当たり前の指摘を受けたので対応してみた。

このブログについて

このブログ自体はChalowというツールを使って作ってるのだけど、今までの経験からコメントとかトラックバックなんかのかっこ良さげな機能は使われないと判断して削っておりました。
※ どうせコメントとかもないし

ただ、確かに更新Pingくらい打てないとGoogleなんかで記事が検索できるようになるまで半日かかるとか泣けてくる自体に。

で調べたところ、Chalowの製作者のブログにこんな発言が。

基本的に chalow は「HTMLコンバータ」。変換と公開を同時にやってる人っ
て意外と多いのかもしれないけど、変換と公開のタイミングがいっしょで
あることは仮定してません。私は別タイミングだし[2004-05-17-5]。
まあ、ともかく私としては、chalow本体でPING打つってのもなあ、と思う
ので放置です。
[Weblogツール三種の神器](http://chalow.net/2004-08-10-4.html)

<<

このブログもDropboxにアップされたChangelogを定期的に取得して生成しているので「生成のタイミング != 記事が新規登録されたタイミング」になってしまいChalow本体にPing送信機能を突っ込むと無駄打ち空打ちが続いてしまうわけです。

基本方針

前項のような理由から、以下のような方針
・更新Pingを空撃ち無駄打ちしない
・Chalow自体の機能として実装しない

さて、どうしたものかと考えたところ、RSSのバックアップを取っておいて新しく吐き出したRSSとDiffが違ってたら更新Pingを送るようなスクリプトを書けばいいんじゃなかろうかという結論に相成りました。

下準備

Chalowの吐き出すRSSについて

で、そういう事が可能なのかと下調べのために吐き出しているRSSを眺めたところ、RSS自体の更新日が毎回生成した日時になっていたので最新記事の更新日に変更。
そうしないと、生成するたびにRSSの内容が変わってしまうから

類似例について

と言ってもちょっと調べると類似例が大量に出てきたので、それを参考に。
[cl.pocari.org - Google Blog Search に ping を送る Perl スクリプト](http://cl.pocari.org/2006-10-10-2.html)

XMLRPC::Liteのインストールについて

っとその前にXMLRPC::Liteをインストールしようとして散々っぱら怒られたのでそれは別記
[2011-07-12-1]

試しにPingserverを準備した

本当に送られているかどうか分からないので、とりあえずPHPで参考までに準備してみた。
※ と言っても、サンプル置いてパーミッションを出しただけ
[2011-07-12-3]

作った

使い方。blog_tmpは、ChalowでHTMLを吐き出しているディレクトリ
$ /path/to/publishPing.pl /path/to/chalow/blog_tmp/index.rdf

|perl|
#!/usr/local/bin/perl

use strict;
use warnings;
use XMLRPC::Lite;
use File::Compare;
use File::Copy;
use Error qw(:try);
my $file = shift(@ARGV);
## 更新通知用のサイト情報
my @parameters = (
'そうだ車輪と名付けよう 3rd',
'http://www.atyks.org/blog/',
'http://www.atyks.org/blog/',
'http://www.atyks.org/blog/index.rdf'
);
## 更新Ping送信用URL(複数)
my %endpoints = (
"google"                => {"method" => "weblogUpdates.extendedPing", "url" => 'http://blogsearch.googlh.co.jp/ping/RPC2' } ,
"test"                  => {"method" => "weblogUpdates.ping",         "url" => 'pingserver-url'} ,
);
## 更新の有無を判断するためのRSSのパスとバックアップファイル用のSuffix
my $sfx = "_bak";
if( compare($file , $file . $sfx) ) {
## 前回の実行時からRSSの内容が変更されていれば登録されたPingサーバに更新通知を行う
foreach my $title ( sort keys %endpoints)  {
my $endpoint = $endpoints{$title};
my $result;
try {
$result = XMLRPC::Lite
-> proxy($endpoint->{"url"})
-> call($endpoint->{"method"}, @parameters)
-> result;
}
catch Error with {
$result = {"message" => "", "flerror" => 1};
};
if( $result ){
print qq/success $title $result->{message} stat:$result->{flerror}\n/
}
else{
print qq/failed $title $result->{message} stat:$result->{flerror}\n/
}
}
}
else {
## no Diff, no Action
}
## 最後にRSSを更新する。これで2度打ちを防ぐ
copy($file , $file . $sfx);
exit;

||<

結論

あれ?動いていると思うんだけど、なんかリアルタイムに収集されているような気がしないな。
なんか勘違いしているかも
だめじゃん

追記 at 2011/07/21

無事、Googleのブログ検索の対象になった様子、更新した後に時間を開けずに検索対象になった。

おそらく要因は以下の二つ
・この時期で作成した更新PingをGoogleに送るようにしたこと
・Googleのブログ検索にここ登録したこと
※ 主に2点目を忘れていたのがネックだったような気がする