2011/12/15

Hokkaido.pm #6に行ってきました

Hokkaido.pm #6に行ってきました

ブログを書くのが遅れましたが、参加してきました。 詳しいレポートはhirataraさんの記事をご覧ください。

今回は関東から5名も参加していただけました。皆様、ありがとうございます!

  • sugyanさん
  • nekokakさん
  • charsbarさん
  • xtetsujiさん
  • hirataraさん

Carton使ってみた

YAPC::Asia Tokyo 2011でCartonの発表をみていたので、その後に使ってみた感想を発表してきました。
簡単にまとめるとお手軽で超便利って感じです。使い方が凄くシンプルなので、発表内容があまりなくて焦りました。
今後もcartonを使っていくんじゃないかと思います。

感想等

akiymさん

Skype::AnyとAnySan::Providerの話し。
いい感じ!と思ったのですが、Skypeクライアントが起動していないとSkype APIは使えないそうなのでちょっと悩みどころです。

nekokakさん

以前、nekokakさんに「ソフトウェア開発のプロセス」を聞きたいとリクエストしていましたが、スルーされた経緯がありました。
しかし、今回は最近実装した分散JobQueue『Clutch』の開発の話しと合わせて聴かせていただけました。
JobQueueも今回リクエストしていたので、完全に「俺得」な内容でした。ありがとうございます。

懇親会ではTengの話しを聞かせてもらって、やはり今後はDBIx::SkinnyじゃなくてTengだと感じました。 余談ですが、JobQueueはSchwartzとGearman、ContainerはScope::Containerを使ってます。

xtetsujiさん

xtetsujiさんは「mod_perl hacks PHP」というタイトルで、PHPがmod_perlの処理フェーズの中でPerlResponseHandlerの部分しか使ってないので他のフェーズはいじり放題という内容でした。この発想はなかったなーと感心してしまいました。尚、発表の内容はフィクションですので、実在の団体とは関係ないそうです。

hirataraさん

PerlのGCがreference counterなので、うっかり循環参照するとメモリリークしたりするわけです。そんな循環参照を見つけたりする方法の話しで、私が主に使うDevel::Cycleも紹介されてました。

sugyanさん

全裸ではありませんでしたが、雪が積もってる中で、なんと雪駄でした!
除雪されてない場所に果敢に突っ込んでいたのが印象的でした。

YAPC::Asia Hokkaidoについて

前からonagataniさんがやりたいと言っていたのですが、ついに動き出すようです。
不安もありますが、可能な範囲でお手伝いしていこうかと思います。

2011/11/20

[Perl][CPAN]動的にsubroutine呼び出しをするSub::Applyを書いてみた

動的にclass methodを呼びたい場合は割と簡単で、以下のように書ける

    package Foo;
    use strict;
    use feature 'say';
    sub new { bless {}, shift }

    sub sum {
        my $self = shift;
        my ( $x, $y ) = @_;
        say $x + $y;
    }

    package main;
    use strict;
    use feature 'say';

    my $obj  = Foo->new;
    my $func = 'sum';
    if ( $obj->can($func) ) {
        $obj->$func( 1, 2 );
    }
    else {
        say "No such method => $func";
    }

しかし、動的にsubroutineを呼びたい場合はちょっと泥臭くなる

    use strict;
    use feature 'say';

    sub sum {
        my ( $x, $y ) = @_;
        say $x + $y;
    }

    my $func = 'sum';

    {
        local $@;
        eval "$func(1,2)";
        if ($@) {
            say "Oops! $@";
        }
    }

    {
        my $code = do {
            no strict 'refs';
            *{$func}{CODE};
        };
        if ($code) {
            $code->( 1, 2 );
        }
        else {
            say "Oops! Undefined subroutine $func";
        }
    }

evalでstringを評価するか、no strict 'refs'してからsymbol tableを確認する方法があります。

速度面を考えるとevalしたくないし、かと言ってno strict 'refs'をして直接symbol tableを触りたくない。
こう言った泥臭いことはmoduleに隠蔽しちゃうのがいいんじゃないかと思ったので、Sub::Applyを書きました。

Sub::Applyの使用例

    use strict;
    use feature 'say';
    use Sub::Apply qw(apply apply_if);

    sub sum {
        my ( $x, $y ) = @_;
        say $x + $y;
    }

    my $func = 'sum';

    {
        # $funcがない場合、croak
        apply($func, 1, 2);
    }
    {
        # $funcがない場合、carp
        local $Sub::Apply::WARNING = 1;
        apply_if($func, 1, 2);
    }
    {
        # $funcがなくても何もしない
        apply_if($func, 1, 2);
    }

CPANgithubにupしてあります
現在のversion(0.04)では、printf等のcore functionは呼び出せませんので注意してください。

2011/11/19

[Perl][ORM][Teng] Tengでbulk_insertする場合はTeng::Plugin::BulkInsertを使おう (追記: bulk_insertがcoreに取り込まれました)

0.14_01からbulk_insertはcoreに取り込まれました!!

Plugin::BulkInsertはまだ残っているようですが、DEPRECATEDです。load_pluginを使わずに、そのままbulk_insertを使えます


Tengでbulk insertをしたくなったのですが、bulk_insertのmethodがないのでSQL::Makerで書いてしまいました。
後でTwitterでnekokakさんにPluginにあるよと教えていただいたので、再実装しなくて大丈夫です!

ちなみに現在(0.14)のPlugin以下はこんな感じ。

Teng/Plugin
    ├── BulkInsert.pm
    ├── Count.pm
    ├── FindOrCreate.pm
    ├── Pager
    │   └── MySQLFoundRows.pm
    ├── Pager.pm
    └── Replace.pm

使い方は簡単。Tengを継承したクラスでload_pluginを呼ぶだけです。後は普通にbulk_insertを使えます

    package MyDB;
    use strict;
    use warnings;
    use parent 'Teng';
    __PACKAGE__->load_plugin('BulkInsert');

    # in your script 
    my $teng = MyDB->new(...);
    $teng->bulk_insert(
        'tweet',
        [
            { id => 1, tweet => 'hoge' },
            { id => 2, tweet => 'fuga' }
        ]
    );

2011/11/13

[Perl][CPAN] App::pfswatch 0.07をリリースしました

変更点

--pipeオプションの追加

--pipeオプションを付けると実行コマンドのSTDINに変更されたファイル名が渡されます。
後はxargsなりで引数に変換するとかしてもらえるといいんじゃないでしょうか。

    $ pfswatch t/ --pipe --exec xargs prove -lr 

しかし、本当に同時に更新されないと複数のファイル名が渡ってこないので微妙。
実行までのintervalをオプションで付けた方がいいかも

Regexp::Assembleを削除

qr//でもいい程度しか使ってなかったので、削除しました。

[Perl][CPAN] Tweet::ToDeliciousをリリースしました

以前から作成しているTweet::ToDeliciousをCPANにuploadしました。
metacpan.orgでは確認したので、そのうち見えるようになるかと思います。

詳しい説明は以前の Tweet::ToDeliciousでリンク付きTweetをDeliciousに保存する を見てください。

VERSION 0.06ではfavoriteしたtweetを'favorite','via:tweet2delicious'のタグを付けて保存する機能を追加しました。
http://packrati.us/が好きになれなかったので自分で作ったわけですが、これで欲しい機能は一通り実装した形になります。

2011/11/11

[Twitter][API] ドメイン名自動リンクのUser Streams APIでの扱い

[Twitter][API] ドメイン名自動リンクのUser Streams APIでの扱い

Tweet::ToDeliciousでTwitterが勝手にリンクにする"example.com"のような文字列を排除しようと試みたのですが、
判別できなかったので諦めました。

ツイートに含まれるのURL情報のフォーマット

通常、User Streams APIでツイート時に含まれるリンクは以下のようにroot.entities.urlに格納されています。
関係ないところは省略しています。

    {
        "entities":
            "url":
                [
                    {
                        "display_url": "example.com",
                        "expanded_url": "http://example.com",
                        "url": "http://t.co/XXXXX",
                        "indices": [0,20]
                    },
                ] 
    }

そして、現在の仕様では"http"が頭に付かない"example.com"のような文字列が含まれていると、"http://example.com"として扱われます。
しかし、この場合はentities.urlにデータは入りません。URLのつもりでツイートしてるわけじゃないから、当たり前と言っていい挙動です。

問題になるケース

問題となるのは、上記のような自動変換される文字列を含み、且つツイートにURLが含まれる場合になります。
例として"example.com http://example.com"とツイートした場合、以下のようなデータが渡ってきます。

    {
        "entities":
            "url":
                [
                    {
                        "display_url": "example.com",
                        "expanded_url": "http://example.com",
                        "url": "http://t.co/XXXXX",
                        "indices": [0,20]
                    },
                    {
                        "display_url": "example.com",
                        "expanded_url": "http://example.com",
                        "url": "http://t.co/YYYYY",
                        "indices": [21,41]
                    }
                ] 
    }

URLに自動変換された文字列のexpanded_urlにはURI schemeが追加され、通常のURLのdisplay_urlからはURI scheme部分が削除されてる状態になっています。
この仕様によりentities.urlの中身からは、どちらが自動変換された文字列なのか判別ができません。
また、ツイート全体のtext情報では全URLがt.coの短縮URLに置換されているので、ここから判別することもできないようです。

2011/11/06

[perl] Tweet::ToDeliciousでリンク付きTweetをDeliciousに保存する

Tweet::ToDeliciousでリンク付きTweetをDeliciousに保存する

Tweet::ToDelicious

github: https://github.com/ysasaki/p5-tweet-todelicious
git: git://github.com/ysasaki/p5-tweet-todelicious.git

Abstract

リンクの付いているtweetをdeliciousに保存してくれるツールです。
hashtagと[foo]というパターンをtagとして登録します。
また、後で振り分けように自動でvia:tweet2deliciousタグも付与します。

Motivation

今まではdeliciousに気になったリンクを保存していたけど、
最近はCrowsnestbitly経由でTweetすることが増えたため、残しておきたいリンクが分散する形になった。
既存のサービスでリンク付きTweetをdeliciousに保存してくれるものがあるが、hashtagしかtagに変換してくれないので自分で書いた。

Install

gitでgithubから最新版をもってきます。

    $ git clone git://github.com/ysasaki/p5-tweet-todelicious.git
    $ cd p5-tweet-todelicious
    $ cp config.yaml.sample config.yaml

TwitterのStreaming APIを利用しているので、自分で開発者登録をしてconsumer_keyやtokenを取得してください。
登録が完了したら以下の情報をconfig.yamlに書き込みます

  • Twitter ID
  • Twitter App's consumer_key, consumer_secret, token, toke_secret
  • delicious's username, password

後はREADMEにある手順通りにcartonで必要なmoduleをinstallして、起動スクリプトを叩くだけです。

    $ carton install --deployment
    $ carton exec -- perl ./bin/t2delicious.pl

VPSとか適当なサーバ上でdaemontools等を利用して動かすのがベターかと思います。
perl-5.14.xじゃないと動かないので注意。use v5.14;の部分を書き換えれば、perl-5.10.xでも動くと思います。

TODO

  • bit.lyとcrowsnestの短縮URLを展開したい ← 追記 2011/11/09 3:00 展開に対応しました

2011/11/03

use VERSION and use feature

use VERSION and use feature

そろそろ新しいperlを使えそうなので、確認しておく。

use $VERSION

    use v5.14;

これは以下のことが起きる

  • compile time version check
  • use feature ':VERSION' if VERSION >= 5.9.5
  • use strict if VERSION >= 5.11.0

VERSIONの互換性を気にするときは以下のように書けばいいんでないでしょうか。

    use v5.14.2;
    use 5.014_002; # for backwards compatibility. see `perldoc version`

use feature

perl-5.14.2の時点で以下の4つがある

  • say
  • state
  • switch
  • unicode_strings

それぞれの機能は以下のようにしてimportできる

    use feature qw(say);

面倒なので、まとめてimportできる以下のbundleが存在する。

bundle|features
------------------------------------------
:5.10 |switch, say, state
:5.11 |switch, say, state, unicode_strings
:5.12 |switch, say, state, unicode_strings
:5.13 |switch, say, state, unicode_strings
:5.14 |switch, say, state, unicode_strings

bundleは以下のように指定する。

use feature ':5.10';

bundle指定で':5.10.x'と書いた場合、xはなかったものとして扱われる。
また、もう使うことはないだろうが、特別なbundleとして':5.9.5'が存在し、':5.10'として扱われる。

the ’unicode_strings’ feature

5.13.8から完全にサポートされて、Unicode関わるバグ(文字列のappend時の挙動とか)を治してくれる模様。
詳しくはperldoc featureperldoc perlunicodeのThe "Unicode Bug"を参照。

perldoc featureにも以下のようにあるので、新規に書く場合は使ったほうがいいのではないでしょうか。

if you are potentially using Unicode in your program,
the "use feature 'unicode_strings'" subpragma is strongly recommended.

2011/11/01

perlbrewとcpanmとcarton

perlbrewとcpanmとcarton

cartonをどこにinstallするのが適切なのかわからんので、とりあえず以下のようにやってる。

  1. perlbrewをinstall
  2. perlbrew install-cpanm
  3. 必要に応じて perlbrew install perl-5.x.y
  4. cpanm Carton
  5. cd $PROJECT
  6. carton install

2011/10/29

App::Prove::RunScriptsで快適テスト生活

App::Prove::RunScriptsで快適テスト生活

公開場所

開発動機

WebアプリケーションのデータストアにMySQLを利用している場合、テストでTest::mysqldを使っていると思います。
しかし、各テストファイル毎にmysqldを立ち上げていると、テストファイルが増加した際に、mysqld立ち上げのオーバーヘッドが問題になります。
これを解消すべく作成しました。

既存の解決策

  1. にひりずむ::しんぷる make test で Test::mysqld を永続化させる方法
  2. Craftworks Tech Blog - Branch Test::mysqld を別ウィンドウで立ち上げたら開発時の prove が快適過ぎる件

問題点

  1. Module::Install::TestTargetは色々と便利なこともできるが、単純にテスト実行前にTest::mysqldを叩くだけには大げさ過ぎる
  2. 裏で先に立ち上げておくのは正直めんどうだし、忘れそう

こんな感じの問題点と普段の開発中はmake testなんて叩かないでproveをメインに使っているということもあり、proveライクに使えるコマンドが欲しいということでカッとなって作りました。

インストール

    $ cpanm App::Prove::RunScripts

使い方

上記コマンドでインストールされたprove_runscriptsコマンドを使用します。proveの薄いwrapperで、before/afterオプションが新規に追加されています。
後は実行したいスクリプトを指定するだけです。複数指定もできます。
xaicronさんの記事にあるsetup_mysqld.plをそのまま利用できると思います。

    $ prove_runscripts --bofore t/scripts/setup_mysqld.pl --state=save -lr t/

2011/10/23

Remedieのニコ動のembedを修正

とりあえず修正したものはgithubにあげてあります。

今月の途中からremedieでニコ動を見ようとすると、以下のポップアップが出てきて閲覧できなくなった。

This video is deleted or does not allow embeds

該当箇所のコードを確認すると、wv_titleの後にfv_autoplay、fv_new_windowを埋め込んでいる模様。
(恐らく)ニコ動側の変更でwv_titleが削除されていたので、wv_idを基準に埋め込むように修正

    diff --git a/lib/Remedie/Server/RPC/Player.pm b/lib/Remedie/Server/RPC/Player.pm
    index 14a959b..37ef936 100644
    --- a/lib/Remedie/Server/RPC/Player.pm
    +++ b/lib/Remedie/Server/RPC/Player.pm
    @@ -42,8 +42,10 @@ sub nicovideo : POST {
         ## Whoa HACK
         my $code = $response->content;
         $code =~ s/document\.write\((.*?)\)/\$("#embed-player").html($1)/g;
    -    $code =~ s/(wv_title.*?)$/$1\n, fv_autoplay: 1, fv_new_window: true/m
    -        or die "This video is deleted or does not allow embeds";
    +    $code =~ s/(wv_id.*?)$/$1\n, 'fv_autoplay': '1', 'fv_new_window': 'true'/m;
    +    if ( $code =~ /isDeleted: true/ ) {
    +        die "This video is deleted or does not allow embeds";
    +    }

         return { success => 1, code => $code };
    }

2011/10/16

YAPC::Asia Tokyo 2011で発表してきました #yapcasia

YAPC::Asia Tokyo 2011で発表してきました

ブログを書くまでが勉強会!

YAPC::Asia Tokyo 2011 公式サイト - http://yapcasia.org/2011/


御礼

まず、私の所属している株式会社アイダックと諸々の支援をしていただいたTマネージャにお礼申し上げます。
旅費と協賛スポンサーの申し込みありがとうございました!


初スピーカー

今回厚かましくもスピーカーとして参加させていただきました。
当日は緊張しましたが、やって良かったなと思っています。

トークに応募するきっかけを作ってくれたHokkaido.pmとそのメンバー、JPAと地方派遣支援で来ていただいたゲストの皆さん、高頻度で自費参加してくださるcharsbarさん、ありがとうございます!


少人数でのWebアプリ開発 CGIからPSGIまでの変遷

現在の部署の歴史が浅いことと私が入社当初、職業プログラマとしてのキャリアがなかったこともあり、
初期の状態は良いとは言えませんでした。
その環境を少しずつ改善し、近代的なプログラミング環境を整える変遷を紹介したものです。

スライドは以下になります。


その他雑感

  • 941さん、色々とお世話になりました。ありがとうございます!
  • 同じHokkaido.pmのあきやまさん(@akiym)のトークが裏番組だった
    YAPC::Asiaは大規模なので、そこまで気にしてられない状態だったと思いますが、これは残念でした。
  • 今年はお昼ご飯の時間が設けられててグッド
    去年は20分しか隙間がなかったので大変だった
  • 東京のPerl Mongerは実は優しい
  • 地方からきている人が思った以上にいた
  • Parumon面白いよ!拡張パック希望
    懇親会で遊んでくれた人、ありがとうございます。次のHokkaido.pmの開始前とかに遊びたい

2011/10/08

全文検索エンジンgroongaを囲む昼下がり@札幌に行ってきました

全文検索エンジンgroongaを囲む昼下がり@札幌


最初の自己紹介のまとめ


  • ここにきている人だけあって、groonga使ってる人が多い
  • Senna, tritonnもちらほら
  • 中の人が札幌に来たので勢いで開催



Groongaの中の人、森さんによる概要


ざっくり概要


  • 全文検索エンジンが出発点
  • データストア能力が強化されてきた
  • 特徴
    • 転置索引
    • 即時更新
    • カラムストア

なぜ転置索引か


  • searchのスループットを重視
  • 転置 > Suffix Array > Signature > 線形
  • indexingは遅い傾向がある

即時更新


  • CGM等ですぐ検索できないと使いづらい
  • groongaではここを頑張ってる
  • リアルタイムに強いということを今日は覚えてかえる

カラムストア


  • 普通のRDBではレコード毎に保存
  • filter, sort, group byは大体必須な機能なので、高速化したい



groongaの使い方とかとか


  • Cのライブラリがある
  • groongaコマンドで操作
  • HTTPもあり。レスポンスはJSON
  • gqtp - groonga query transfer protocol
    • HTTPよりも効率はいい
  • memcachedプロトコルも話せる

SennaとGroonga


  • Senna
    • アイルトン・セナが速いから付けた
    • 他のRDBと組み合わせて使う
  • Groonga
    • MySQL, PostgreSQLと使うこともできる

森さんがいろいろ


  • Cライブラリで直接扱うと速い
  • MySQL経由だとSQLのうんぬんがあるので、それほど早くないかも
  • ひとつのDBに対してMySQL, HTTP, Cライブラリからなど同時にアクセスできる

MySQL + Sennaの不満


  • MyISAM
    • メンテが大変
  • 5.0
  • 更新しながら、検索さくさくできない
    • MyISAMは書き込み時にreadもブロックしちゃうよね

MySQL + Groongaでは


  • Groongaでも更新せな!っていうのを頑張ってる
  • プラガブルストレージエンジンに対応
  • データストアがそもそもあり



休憩




Groongaの構造とデータの流れ


資料を見た方がいい

http://www.clear-code.com/blog/2011/10/5.html


ちょっとだけメモ


  • パトリシアトライ
    • トライ(Trie) <- retrieval
  • lexicon
      - 転置索引がゼロになっても、こっちは消さない
    • テーブル構造にしているのは今後拡張できるように
    • トークンのポジションも保存するかどうか選べる
    • 重みも記録できる



質問タイム


  • Groongaのこれからやっていきたいこと
    • 性能を良くする
      • インデックス構築はまだ早く出来る
    • versioned indexをいれたい
      • あまり使わないのはコンパクトにしたりとか
    • トランザクションは検討したい
  • スケールアウト
    • MySQL + Spider + Groonga が現状はいいかも
  • MySQL InnoDBの全文検索とGroongaどっちが速いの?(森さん)
    • 都合よくデータでてきた!
    • MySQL + Groonga (storage mode)の方がindexsingがやっぱり速い
  • 事例とか
    • 書いていいかわからないのでカット
  • 文章数はどのくらいまでいれたことがあるか
    • twitterのデータを入れたときが多かった
    • 1nodeで1000万レコード。まあ扱えている感じ
  • gqtpのバイナリプロトコルのドキュメントはあるのか
    • ないようです
    • source読んでね
  • データベースファイルをmvすると問題あるような?
    • rubyのライブラリからmvしたやつを使うと怪しい

2011/09/30

DOZENS(ダズンズ)にネームサーバを移行しました

先日引越したのですが、その際にちょっと手違いで1週間弱固定回線が使えない期間ができてしまった。
普段はemobileで大丈夫だけど、自宅サーバで管理していたネームサーバが利用できないのは不便です。

Amazon Route 53を使おうか悩んでいたところ、DOZENSのtwitterアカウント @dozens_jp に営業をかけられたので使ってみることにしました。


DOZENSとは

DNSのホスティングサービスです。コントロールパネルからぽちぽち設定するだけでレコードの設定ができます。

Google Apps用の簡単設定機能もある(らしい)


料金

  • 12レコード 無料
  • 24レコード 100円/月
  • 36レコード + TTL変更 1000円/月
  • 192レコード + TTL変更 5000円/月
  • 612レコード + TTL変更 10000円/月

* 2011/09/30時点での料金です


ドメイン数やクエリ数での課金ではなく、レコード数によるのがちょっと面白い。

100円/月までのプランに収まるなら、VPS等で自分でネームサーバを運用するより安くつくかも

NSレコードは自動で設定されるため、レコード数のカウントには入らない模様。


レコードの設定方法

シンプルで使いやすい管理画面があるので、Web上からさくさく設定して終わりです。


  1. レジストラの管理画面でDOZENSで管理したいドメインのネームサーバを以下に設定する
    • ns1.dzndsn.com
    • ns2.dzndsn.com
    • ns3.dzndsn.com
    • ns4.dzndsn.com
  2. DOZENSの管理画面から[Add a domain]をクリックして管理したいドメインを設定
  3. 追加されたドメインの[EDIT]を押す
  4. [Add a record]を押してポップアップに下記の項目を入力して、[create]をクリック
    • レコード名
    • レコードタイプ
      • A, AAAA, CNAME, MX, TXTの選択式
    • TTL
      • 安いプランでは2時間固定
    • Priority
      • MX以外は大体いらないはず
    • Content
      • IPアドレス等を記載

まとめ

Route 53だとドメイン毎とクエリ数で課金されるので最低でも1ドル/月かかるので、レコード数が少ないならDOZENSが良い感じです。

後、使用者がいるのかわかりませんが、 REST API が用意されています


最後に

下記のリンクから登録していただくと、私とあなたの両方に3レコード追加されます。使ってみたいと思った方はよろしくお願いします。

http://dozens.jp/i/ulWIxq

2011/09/23

Jenkins勉強会 札幌のメモ

Jenkins勉強会 札幌


CI概論 @cactusman


CI


  • 頻繁にビルドしろ
  • ナイトリビルド、デイリビルドの延長線上
  • 自動ビルド、自動テストを推奨

広まらない理由


  • SCM必須
  • テスト必須
  • CIサーバ
  • チームメイトの理解

あるといいもの


  • BTS
  • インスペクション
  • XFD (eXtreme Feedback Device)

CIは最近流行ってきている


  • EC2, VPS
  • XPの浸透
  • Jenkinsなどのツール類の発展
  • ノウハウ

問題やパターン


スローテスト問題


  • テスト実行に時間がかかりすぎる
    • テスト実行数の増加
    • 非効率なテスト
    • 依存関係
    • システムテスト的なもの
  • ビルド自体も同様

解消方法


  • テスト自体のパフォーマンスチューニング
    • TDD的なテストは捨てる
    • DBなどはモック化、インメモリ化
  • 実行単位のスケジュール
  • 実行単位の細分化して、並列性をあげる
  • スケールアップ
  • スケールアウト

狼少年問題


  • テストが通らない、インスペクションでの警告が常用化
  • OSSでも割とある

解消方法


  • 状態を把握する
    • テストの失敗や警告の増減に注目
  • テストの最小化
    • やる必要があるかどうか常に考える
  • 問題のあったところ、デグレードしたところを重点的に
  • インスペクションで問題のない箇所はレビュー後にignoreにする

Pre-Tested Commit


  • コミットする前にテストを実行するパターン
  • CIサーバに差分を送って、テスト等を行う
  • オールグリーンならコミット、レッドならコミットできない
  • TeamCity(IntelliJ IDEA)で機能あり
  • Jenkinsでも要望がある
  • DVCSで代用することも可能?



Jenkins概論 @cactusman


Jenkins


  • OSSのCIツール
  • 簡単、手軽、親切
  • プラグインで機能拡張
  • 各OSごとにインストーラがある
  • CIのデファクト?

Jenkisの役割


  • チェックアウト
  • ビルドスケジュールの管理
    • 1時間間隔とか
  • 通知
  • レポーティング
  • ログの保存

よくある誤解


  • JenkinsがJavaだから、Javaしか扱えないんでしょ
  • Java知らないです

誤解への回答


  • Javaの知識はなくてもいい
  • ビルドにsh, batを使える

高度な機能


  • トリガー
  • plugin
    • wikiを見てから聞け
  • Jobのチェーン
    • A -> B -> C, B -> D
  • CLI
  • クラスタリング
    • マスタ/スレーブ形式
  • RESTのAPI

QA


  • サーバの移行は?
    • .jenkinsを固めて、転送する



Trac + Jenkinsで始めるCIのある開発 @shuji_w6e


自己紹会


  • @shuji_w6e
  • Blog やさしいデスマーチ

Jenkinsと私


  • 2009年末に個人的に導入
  • 2010年夏ごろ、社内開発環境で導入

現代のソフトウェア開発の特性


  • 複雑性
  • 短納期
  • 超大規模または超小規模
  • 開発手法の変化

現代ソフトウェア開発の3本柱


  • バージョン管理
  • テスティング
  • 自動化
  • (チケット管理システム)

導入の手順


  • バージョン管理
  • チケット
  • テスト
  • 自動化

バージョン管理とテスティング


  • 効果的な自動化に必要な要素
    • 継続的なテストとフィードバック
    • テスト != 品質保証
  • その他の自動化
    • ビルド、パッケージング、デプロイ
    • 静的解析、ドキュメンテーション

導入事例


開発の流れ


  • tracで作業を洗いだしてチケット化
  • Eclipse等でコードを書く
    • 可能なかぎりユニットテストを行う
    • TDDとペアプロ
  • Subversionにコミット
    • CIでテストが通るか確認する
  • Tracのチケットをクローズ

開発の流れ 自動化部分


  • Subversionにコミット
  • JenkinsCIにコミットを通知
  • Mavenによるビルド・テストの実行
    • 成功時はパッケージを作成
    • ビルド/テスト失敗時は、IRC/メールに通知

変化したこと


  • Tracの活用により作業漏れが減った
    • ファイルサーバのExcelは見ない
  • コミット間隔が細かくなった
  • ユニットテストを実施している部分の品質があがった
  • JenkinsCIが常に監視しているので、問題が起きた場合にすぐ解るようになった
  • 開発に集中できるようになった

導入まで


  • 「よく解らない」に対する抵抗
  • メリットが説明・理解させにくい
    • やってみれば解る
    • 効果が出るまで時間がかかる
  • ある程度は強引に導入

導入に失敗しないため


  • 導入失敗時には「次」はない
  • 同調できる仲間を作っておく
  • ノウハウを勉強会や書籍で勉強する
    • 実際に手を動かして使ってみる
  • 導入経験のある人を巻き込む

導入事例まとめ


  • 開発スタイルは「文化」
    • 内部の「文化」は変えられる
  • メンバーの半分の意識が変われば自然に変われる
    • 1/6から2/6は大変
    • 3/6から4/6はそうでもない

構成事例


TracからJenkinsへ


  • HudsonTracPlus プラグイン
    • タイムラインにビルド結果を通知
    • Jenkinsのビルドページへのリンクとかwikiフォーマット

JenkinsからTracへ


  • Trac プラグイン
    • コミットログからTracへのリンク

Windowsサーバの場合


  • Trac Lightning

Google Code


  • バージョン管理、チケットはGoogle
  • VPSでJenkins

Maven


  • Javaはつかないので省略

デモ中の質問等


  • Jenkins自体で256MBくらい
  • ジョブは別プロセスで動かすのでオーバーヘッドがあるかも
  • CPUはそこまでいらないかも



Jenkins Plugin開発、ハック(@cactusman)


core, pluginのハックの前に


  • shell script等で対応できないか
  • 今ある機能でなんとかなるか
  • coreよりもpluginでいいのではないか
    • 拡張ポイントを見てから

Jekinsのビルドとハック


  • 必要なもの


    • jdk6
    • Maven
  • ビルド


    • git clone hogehoge
    • cd jenkins
    • mvn install -Dskip-test-harness的ななんか
    • 詳しくはwiki
  • IDEでの開発


    • NetBeans(6.7+)
    • Eclipse
    • IDEA
  • URLマッピングはStapler

  • ViewはApache Jellyによって記述
    • GroovyやJRubyが使用可能

Pluginの作り方


  • 公式Pluginを参考にする
  • チュートリアルがwikiにある https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial

オススメぽいPlugin


  • Task Scanner Plugin
    • XXX、TODOとか攫ってくれる
  • Change Log History Plugin
    • Jenkinsの設定を変更した時に変更履歴を見れる

2011/08/20

札幌MySQL#1に行ってきました

札幌MySQL勉強会

箇条書きですがメモを載せておきます

MySQL MHA

目的

  • SPOFをなくしたい
  • マスターのSPOFをなくすのは難しい

障害対応の課題

  • レプリケーションは非同期
  • どのスレーブが最新か判断する必要がある
  • スレーブ間のズレを修正する
  • これを全自動でやる

アーキテクチャ

  • Pure Perl
  • MySQL 5.0以降
    • binary logのformat versionの都合で5.0から
  • MySQL-MasterHA-Manager
    • Config::Tiny, Lod::Dispatch, Parallel::PreforkManager, DBD::mysql
  • MySQL-MasterHA-Node
    • DBD::mysql

内部的な動作

  • SQLスレッドが実行を終えるまで待つ
  • 会心スレーブのリレーログのヘッダを解析して各スレーブに適用する

特徴

  • マスターの稼働監視からフェイルオーバーまでを自動でできる
  • フェイルオーバーが秒単位で可能
  • 非同期レプリケーションでもスレーブ間の同期が取れる
  • 任意のスレーブを新マスターにできる
  • いくつかの箇所から外部スクリプトを呼ぶ昨日がある
    • 電源OFFやIPアドレスのフェイルオーバーなどに使う
  • インストール/アンインストールにあたり現在のmysqldプロセスやレプリケーションを止める必要がない
  • MHA自体は追加の負荷をかけない
  • ストレージエンジンに依存しない
  • バイナリログのフォーマットに依存しない
    • statementでもrawでも大丈夫

拡張ポイント

ケーススタディ

  • DeNAのサービスに対してMHAを導入
  • MySQLは滅多にクラッシュしないけど、OS、H/W障害によって落ちる
  • OSダウンによるフェイルオーバーには、ダウン検知に10秒、フェイルオーバーに4秒
    • マスターの生死判定
    • フェイルオーバー可否判定
    • フェイルオーバー処理

デモ

  • 3台構成 Master1 Slave2
    • master centos6-1
    • slave centos6-2
    • slave centos6-3
  • 設定ファイルでスレーブの中からマスターになる候補を決められる
  • masterha実行時にどのサーバーがmasterか自動検知

既存のソリューションに対する優位性

  • マスター障害でも整合性をたもってレプリケーションを再開できる
  • スタンバイサーバがいらない
  • フェイルオーバー時間が高速
    • アクティブ/スタンバイ構成のDRBDでは1分単位
  • MySQL Cluster/Galeraに対する優位性
  • MySQL-MMMは怖い

その他の特徴

  • 任意のスレーブを新マスターにできる
  • フェイルバックをするのが面倒
  • 準同期レプリケーションを併用することで、データ消失をほぼ防げる

サービスの増強と縮退

  • ゲームタイトルの人気を正確に見積もることは困難
  • 想定外の人気が出た場合
    • スレーブを追加
    • 水平分割でマスターを増やしていく
    • マスタのH/Wを増強する

マスターを別マシンに移行したい

  • マスターを別マシンに移す
  • メンテナンス時間を設ければ簡単
  • ダウンタイムなしでマスターに切り替えるのが理想
  • 0.5から3秒くらいでできれば多くの場合は許容範囲

書き込みブロックをどうするか

  • アプリケーションのユーザをdropする
    • 新規だけエラーになる
    • 接続済みはエラーにならない
    • 接続済みのセッションが終了しない限り、更新がおわらに
  • set global read_only = 1
  • OSCのときは3秒で切替だったけど、最適化して1秒くらいになった

MHAでの高速マスター切替

  • masterha_master_switchで手動切替もできる
  • 切替前と切替後の構成を表示して、確認がある
  • webアプリなら一回エラーになっても、もう一回クリックして動けば許される雰囲気
    • 今のところ苦情はきてない

質問

  • slaveの昇格の設定
  • MasterHA自体が落ちた場合は
    • pacemakerとかでMasterHA自体をHAする

MySQL開発者向けチューニング

ディスクI/O性能を常に意識する

  • HDDは遅い

一部のクエリだけが問題を起こす

  • 1%の法則
  • 代表的な悪い例
    • 大量のレコードをスキャン
    • 個々の実行効率は悪くないが大量に実行される
      • スロークエリにはでない
      • 何かツールを後で紹介
    • 長時間ロックを保持

tcpdumpとmk-query-digest

  • スロークエリログが有効になっていなくても実行頻度の高いクエリを取れる

クエリの実行計画に注意する

  • EXPLAINの読み方を習得する
  • MySQLのオプティマイザが判断を謝ることがあるので気をつける
    • とくにsortが絡む場合
      • FORCE INDEXを使う
    • コストベースなので、テスト環境と本番環境で実行計画が異なることがある

計算量とランダムアクセスを意識する

  • SELECT xx FROM t WHERE xxx LIMIT 100000, 20

スレーブの性質を理解して使う

  • スレーブはシングルスレッド
    • CPU効率の悪い更新処理はスレーブ遅延を招く
    • innodb pluginの圧縮とか
    • 長時間かかる処理はその実行時間分だけレプリ遅延になる
  • テンポラリテーブルとの相性がわるい

トランザクションを意識する

myslowtrancaptureで遅いトランザクションを特定する

  • githubにある
  • 実行に一定時間以上かかったトランザクションを探し出す
  • 誰がロックしているかも表示する

データサイズに常に気を配る

  • 必要以上に大きなデータ型を使うべきではない
    • datetimeよりtimestamp
    • varcharよりint
    • intよりもsmallint
  • 古いデータをメインテーブルから削除する
  • index

INDEX

  • ルート→ブランチ→リーフ→実データ

範囲検索を注意して使う

  • データを削除するとき
    • delete文で削除されるものをslaveで空読みして、メモリに載せてから実際にdeleteしてレプリ遅延を防ぐ

Covering Index(インデックスだけを使う検索)

  • SELECT key1 FROM th1 WHERE key1 IN (1,2,3)
  • explainでusing indexになっていればOK

マルチカラムインデックスと範囲検索

  • カーディナリティに注意

Covering Indexに帰着させる

  • SELECT a,b FROM tbl WHERE secondary_key < 100;
  • a, bをindexにしておく
    • indexを安易に増やすのがいいのか考える

INSERT性能とメモリ量の関係

  • リーフブロックにもうエントリーが入らなくなると、追加のブロックが確保される
  • ランダムINSERTは虫食い状態になりやすい
    • indexサイズが増える
    • ディスクI/Oが増える
  • インメモリでINSERTを完結させる
    • 10000rows/s超える
  • 高速ストレージでも実は状況はさほど改善しない
    • insert buffer? ランダムinsertでも毎回readしない
    • FusionIOでも5000rows/s程度
  • 時系列データはレンジパーティション
    • indexはパーティション毎に作られる

データブロックがどのように読まれるか

  • 全体の3%しかアクセスしなくても、ブロック単位で読み込むので思ったよりも多くメモリが必要
  • 剰余ベースは効率がわるい
  • 範囲ベースの振り分けは効率がいい

Blogテーブルの扱いを考えてみる

  • タイトル、本文
  • 大抵の人は一覧しかみない!
  • 長いBLOB/TEXTは全クエリを遅延させる
    • 本文が別ブロックにはいってしまうことがあるから
  • 本文を別テーブルに切り出す 1:1関連

ロック競合

  • ロックは必要になるまで確保せず、不要になったらすぐにCOMMIT/ROLLBACKで解放する
  • ロックを確保した後に、何秒もかかる可能性のある処理をしない

Version Numberデザイン

  • 楽観ロック
  • テーブルにVERSION列を追加

SELECT *を多用しない

  • 必要な列だけ返すこと

省スペース化

  • JSONデータ等でkeyを小さくするとか

データ型の指針

  • FLOATを使わない
  • NOT NULLを使う
  • TEXT/BLOBを使わない 
  • UNSINGEDを使う
  • INT(1)は1バイトじゃない

EXPLAINを見る

  • type=indexかつ「Extra: Using index」ではないクエリは使用不可
  • 巨大LIMITはダメ
  • covering indexにする

LEFT OUTER JOINしない

ストレージエンジンを混在させない

  • キューサーバとしてQ4Mを独立して用意するのはあり

重複したインデックスを持たない

  • INDEX(c1), INDEX(c1,c2)

LOAD DATAを使わない

  • レプリケーション遅延を招く
  • LOAD中にマスターがクラッシュすると、フェイルオーバーできないことがある

複数マスター間でのデッドロックに注意

  • 異なるmysqldでのデッドロックは自動検出されない
  • アプリ側でIDのソート順にロックをかけることで回避できる

履歴系データはレンジパーティション

2011/07/31

Sapporo.js 2011-07-31 参加レポート #sapporojs

今日はSapporo.js 2011-07-31に参加してきましたので、そのレポートを。
次回も可能であれば参加したいです。

5.4 関数型

写経

    var mammal = function(spec) {
        var that = {};

        that.get_name = function () {
            return spec.name;
        };

        that.says = function() {
            return spec.saying || '';
        };

        return that;
    };

内部にプライベートなthatを用意してカプセル化を実現

    var dog = mammal({name:"Dog", saying: "Bow"});

    document.writeln(dog.get_name()); // Dog
    dog.name = "Cat";
    document.writeln(dog.get_name()); // Dog

引数が分かりづらいのでこうして見る

  • 型チェックの追加
  • specに必要なkeyを明示的にする

改善後

    var mammal = function(spec) {
        var that = {};

        if ( typeof spec === 'object' && spec ) {
        } else {
            throw "spec should be an object';
        }
        var name   = spec.name   || 'mammal';
        var saying = spec.saying || '';

        that.get_name = function() {
            return name;
        };

        that.says = function() {
            return saying;
        };

        return that;
    };

改善前のはspecを先に定義しておけば、nameを書き換えられる

    var dogSpec = { name: "Dog", saying: "Bow" };
    var mydog = mammal(dogSpec);
    console.log(mydog.get_name()); // Dog
    dogSpec.name = "Cat";
    console.log(mydog.get_name()); // Cat

改善後のように変数、関数を別定義にしておけばちゃんとカプセル化される


Q. 最初に出てきた引数myは必要なのか?

    var mammal = funciton (spec, my) {
        // 省略
    };

A. 本に使用例も出てきてないし、誰もいい使い方が思いつかないから必要なさそう


親の関数をoverrideする前に変数に入れておけばOK

    var coolcat = function(spec){
        var that = cat(spec),
            super_get_name = that.superior('get_name');

        that.get_name = function(n) {
            return 'like ' + super_get_name() + ' baby';
        };

        return that;
    };

    var myCoolCat = coolcat({name: "Bix"});
    console.log(myCoolCat.get_name());

P.63までやった。次回は 5.5 オブジェクトのパーツ(P.64) から


LT

jQueryを読んでみよう @tricknotes さん

まずはgitからソースコードを持ってくる

git clone https://github.com/jquery/jquery.git

buildするにはREADMEを嫁

  • node.js 0.2
  • git 1.7
  • GNU make 3.8

今のHEADは1.6.3pre

いきなりsourceを読んで前回敗北したのでtestを見ていく

  • QUnitで書かれてる
  • test/index.htmlをブラウザで開くと実行していく様子が見れる
  • test/unit/*.jsがテストコード
  • test codeから読むと何がしたいコードなのかわかるので、そこを頼りに読み解く

jQueryのcodeの中にはThe Good Partsがいっぱいある

    var jQuery = (function(){})(); // 無駄なglobal varをつくらない

Sapporo.js-webの裏事情 @tricknotes さん

Sapporo.js-web

  • nodeで動いてる
  • JoyentCloud

    • 通常はxxxxx.no.deというドメインになる
    • グローバルIPも貰える
    • sshも使える
    • git pushでdeploy
    • 1ヶ月くらい申請でかかる!
    • gcc v3.4.6, makeとかは入ってた
    • solarisの模様

ベースはLooseleaf.JSで作成

githubでサイト自体も公開

@onjiro_mohyahya さんがテーマのベースを作るので、その後pull-requestをお待ちしてます

2011/07/17

Hokkaido.pm#5の参加レポート一覧(7/22更新)

Hokkaido.pm#5に参加レポートで発見できたものを載せておきます
blogに書くまでが勉強会なので、運営スタッフへの文句でもいいので書いていただけるとありがたいです。

2011/07/18 13:40
@akiymさん、@hirataraさん(LT)追記

2011/07/18 22:02
@lapis_twさん追記

2011/07/19 23:54
@nekokakさん追記

2011/07/21
@koji_magiさん、@keroyonn_さん追記

2011/07/22 0:01
@xtetsujiさん追記

2011/07/16

Hokkaido.pm #5

Hokkaido.pm#5のメモを公開しておきます。

Perl/SDL @charsbarさん

  • SDLの紹介
  • ニコ動に動画もある
  • CPANにあるよ
  • Perl Foundationの肝いりの詳細な資料あり
  • Rubyでは本まででてる!
  • Marc LehmannさんがGames::Sokoban
  • Games::Sokoban::ControllerをCPANにupした
    • ascii artでまずかいた
    • その後SDL化
  • 動くものができるのでLTとかにいいよ!

xtetsujiさん

  • リモートメールの中の人
  • Apache + mod_perl2
  • 古いCGIを改修とかの仕事がまわってくることもあるので対処用としても使える
  • mod_perl1 1996, mod_perl2 2002
  • mod_perl1とmod_perl2で文法違うから気をつけて
  • mod_rewriteのリファクタリングとかをPerlTransHandlerを使う
  • Apache2でSMTPサーバ
    • posftfix pipeとかではメール受信時のforkコストが高い
    • 重たいモジュールもごりごり使える
  • qpsmtpd
    • 良さげ
    • エンジン切替ができる

libperl++ lapis_tw

  • 動きませんでした
  • PODとReadmeの中身が違う
    • ライブラリのバージョンも違う
    • MSVCで使えるって書いてあるけど、やっぱり使えない
  • TODO、XXX、FIXMEだらけ!
  • 次回までに動作させる

@nekokakさん

  • @akiymaさんが推しまくったのでこれた
  • API, gateway開発
  • お母さん役
  • DevOps的な社内取り組み
  • YAPC::Asia 2010 省サーバ運用でベストスピーカー賞次点
  • カンファレンスは情熱をもらうところ
  • 自プロダクトを使いたけど、今のプロジェクトでは使えない
    • 折り合いをつける
    • ドックフード -> eat your own dog food
    • 自分で使うために作る
    • 有りもので満足できないなら作る or すごい人に凄い人に作ってもらう
  • DBIx::Connector
    • 有名で評価も高いけど、DBIx::Handlerを作った
    • Ore Oreを見極める
  • 尊敬するエンジニア
    • 樋口さん
      • MySQLのHandlerSocket
      • 使えそうなケースがあったので相談したけど、「InnoDBでいいんじゃない?」
      • 超かっこいい
    • tokuhirom
      • 凄いとんがってる
      • 豪快エンジニア
      • 仲間を大事にすr
      • エンジニア視点でビジネスのことを考える
      • 監視にも積極的
    • 他にもいっぱい
  • 本当に必要なのかを考える
    • 導入難易度
    • 運用
    • パフォーマンス
  • ビジネス的に是か
  • エンジニアとしての意識
    • 作るだけで終わらない
    • 使うだけで終わらない
      • フィードバックを送る
    • やるなら徹底的に
  • 自分自身
    • 社会人2,3年目までリーマンプログラマ
    • WEB+DBのPerlHacker座談会記事で目覚める
    • Shibuya.pmに出席
  • やってきたこと
    • CPANモジュールを漁る
    • blog書く
    • module書く
    • CPANにup
    • 転職
    • Shibuya.pm LT
    • YAPC::Asia
  • DevOps
    • 開発者と運用者の垣根をなくす
    • 自分たちのサービスに愛を
    • 運用者と開発者のコラボ
  • YAPC::Asia 2011
    • もうすぐスピーカー応募始まるよ
    • いつも同じメンツ?
  • WEB+DBのPerlHackersHubに寄稿

テスト駆動開発 @dont_cocoa

  • 初スピーカー
  • 仕事ではほとんどPHP
  • 今はPerl
  • TDDBC札幌
    • @t-wadaさんが講
    • 講義
    • ペアプロ形式
    • 2二日目はテストの無いレガシーコードを
  • 半年間実践
  • 基本
    • 仕様からテストコードを最初に起こす
    • 最初は失敗させる
    • 実装
    • テスト実行 -> 成功
  • 一気に書きたいのを堪えて、テストが通る最低限のコードだけ書く
  • バグ
    • 再現コードを書いてから、修正
  • やってみて感じたこと
    • 見通しのよいコードを書ようになた
    • 進捗状況がわかりやすくなった
    • テストの粒度が重要
    • 作業量は変わらない

LT

Base64を再実装する @akiymさん

  • Base64では読みあげられない
  • じゃあ日本語だ
  • Acme::Collector64

道具のいらないHello, world koji**さん

  • perldoc

ウイスキーとPerl @hirataraさん

  • uWSGI
  • dotcloud
  • nonblockingモードがある
    • Coro, AnyEventを見る
  • fastroute
  • subscribe

2011/06/30

ExtUtils::MakeMakerでMETA.ymlにmeta情報を追加する方法

repository情報をCPANに載せたい

githubで管理しているモジュールをCPANに上げたら、(誰かがpull requestを送ってくれるかもしれないので)repository情報をCPANに載せたいところです。

Module::Installを使用している場合は、 auto_set_repositoryを使うと勝手にセットしてくれますが、ExtUtils::MakeMakerでの書き方を知らなかったので調べました。

META_MERGEを使う

    WriteMakefile(
        NAME         => 'MyApp',
        VERSION_FROM => "lib/MyApp.pm",
        ABSTRACT => 'My great Application!!',
        PREREQ_PM => {
            'ExtUtils::MakeMaker'     => 6.31,
            'ExtUtils::Install'       => 1.46,
        },
        META_MERGE => {
            resources => {
                license => 'http://dev.perl.org/licenses/',
                repository => 'git://github.com/example/myapp.git',
            },
        },
        LICENSE   => 'perl',
    );

META_ADDでも追加できるがMETA_ADDはdefaultのmeta情報を上書きするので、とりあえずMETA_MERGE使っておけってExtUtils::MakeMakerのPODに書いてありました。

2011/06/29

App::pfswatchをリリースしました(0.04に合わせて修正)

2011-07-01 追記

配布場所

http://beta.metacpan.org/module/App::pfswatch

概要

ファイルの変更を検知して、指定のコマンドを実行するツール

インストール

CPANから

    cpanm App::pfswatch

CPANで見つからない場合はgithubから

    git clone git://github.com/ysasaki/p5-app-pfswatch.git
    cd p5-app-pfswatch
    cpanm .

使い方

App::pfswatchに付属しているpfswatchコマンドを使います

2011-07-01 0.04で修正

-eは残りの引数すべてをCOMMANDとして受け取るようになりました

    $ pfswatch lib/ -e echo Hello, world

監視するパスを与えない場合はカレントディレクトリが監視対象になります。
指定のコマンドを実行後はまた監視状態に戻ります

2011/04/09

Log::Minimalの出力先をファイルに変更するLog::Minimal::Fileを書いてみた

配布場所

github https://github.com/ysasaki/p5-log-minimal-file

インストール

git clone git://github.com/ysasaki/p5-log-minimal-file.git
cd p5-log-minimal-file
cpanm .

作成した理由

Log::Minimalの手軽さがナイスだったのですが、出力先をファイルに変更するのがめんどうだったので作成しました。

使い方

Log::Minimal::File->guard($filename)を呼ぶとguardオブジェクトが返ってきて、
guardオブジェクトが消えるまでは指定したファイルに書きこまれます。

    use strict;
    use warnings;
    use Log::Minimal;
    use Log::Minimal::File;
 
    infof("send to STDOUT");
 
    my $guard = Log::Minimal::File->guard('/tmp/your.log');
    infof("send to your.log");
    undef $guard;
 
    infof("send to STDOUT");

TODO

  • Log::Minimal::Fileの名前で大丈夫か?
  • 別途Log::Minimalをuseするのはなんかカッコ悪い
  • 実装方法がいまいちな気がする

2011/03/24

O'reillyでEbookをまとめ買い


被災者支援キャンペーンでEbookが半額だったのでいっぱい買ってしまった!

検索と発見のためのデザイン
GDBハンドブック
Binary Hacks
Linuxシステムプログラミング
プロダクティブ・プログラマ
ソフトウェアアーキテクトが知るべき97のこと
実用Git
プログラマが知るべき97のこと
C++クックブック
イノベーションの神話
キャパシティプランニング
並行コンピューティング技法
Real World Haskell
RESTful Webサービス

2011/03/23

bashのexceとはなんぞや

発端

    #!/bin/bash
    exec 2>&1
    somecommand

というコードがあって、exec 2>&1が何をしているかはわかるけど、内部はどうなっているのか知らなかった

execってsystem callにあるよね

exec(2)は既存のプロセスのまま新しくコマンドを実行する

例えば

    $ exec ls

上記コマンドは既存のshellのプロセスのままlsを実行して終了する。実行中だったshellはexecされたら、lsになってしまうのでshellも結果として閉じる。

    $ ls

だとfork(2)して子プロセスでexec lsしているので、shellは終了しない

bashのexecはなんだよ

よくわからないからbashのsourceを読んでみる。Open Sourceに感謝する瞬間である。

Bash公式からダウンロード。tar ballを展開して、中身を改める。

ざっくり中身を見るとbuiltins/exec.defが怪しいので中をあらためる。そうするとshell_execveが見つかる。これを追いかけると以下のようになる。

builtins/exec.def
↓
shell_execve関数発見
↓
execute_cmd.cにあり
↓
int shell_execve (command, args, env)が見つかる
↓
execve (command, args, env);
↓
こいつはunistd.hで定義されているexecve(2)のようだ

眠いので限界です

次回へ続く?

2011/03/20

第1回 Movable Type勉強会 in Hokkaido 参加記録

第1回FacebookMovable Type勉強会に参加してきました。

さっくりと今回のまとめ

  1. Facebookの「いいね!」は少なくても意外と効果がある
  2. Facebook広告のコスパがいい。現在はセグメントをかけない方が良さげ
  3. hootsuiteは便利
  4. ポポポポーン
  5. Facebookページはiframeで表示させていた
  6. 懇親会の同じテーブルでFacebookを使った新手のイジメがあった

イジメは冗談です。
あまり積極的にFacebookを活用していなかったので、いろいろと参考になる話しが多かったです。

今回はiframeで表示するFacebookページの管理はMTから行いましたが、このプラグインは来週火曜日に公開になるそうです。
個人利用は無償とのことでしたので、興味のある方はスカイアークさんのところ公開されるのを待ちましょう

2011/03/09

アーキテクチャスタイル

システムアーキテクチャ構築の原理の読書メモ

ソフトウェアパターンの分類

一般に以下の3つに分類される

  • アーキテクチャスタイル
  • デザインパターン
  • 言語イディオム

この3つの違いはシステム上でのレイヤーの違いで、アーキテクチャスタイルはシステムレベル、
デザインパターンはソフトウェア設計、言語イディオムはもっとも具体的な言語固有の問題の解決方法を表す。

アーキテクチャパターンのメリット

デザインパターンと同様で直接の解決策だったり、土台に利用したりもできる。
また一般的なパターンであれば、作業者のシステムの理解も早くなる。

アーキテクチャスタイル

  1. パイプとフィルタ Pipes and Filters

    • メリット
      • フィルタ処理が独立化するので変更、再利用が用意
    • デメリット
      • 状態情報の共有が困難
      • フィルタ間でデータ変換のオーバーヘッドがある
      • エラー処理が難しい
  2. クライアント/サーバ Client/Server

    • メリット
      • 複雑な処理の集中化
      • 機密性
    • デメリット
      • クライアントとサーバが同一マシン上ではない場合のオーバーヘッドの高さ
  3. 階層化(ティア)コンピューティング Tiered Computing

    それぞれ段階層がクライアント/サーバの役割する

    • メリット
      • 階層ごとに関心事を分離できる
      • 階層の再利用が可能になる
    • デメリット
      • 階層間の通信のオーバーヘッド
      • システム要素数の増加による追加開発の複雑さ
  4. ピアツーピア Peer-to-Peer

    各ピア(システム要素)がクライアント/サーバとなるが、中央サーバを必要とせずピア同士で自由に通信する

    • メリット
      • スケーラビリティの高さ
    • デメリット
      • 中央ピアリストが入手できないと、ピアのネットワーク分断が起こりやすい
      • 任意の時点でのシステムからの特定の応答が保証するのが困難
      • どういうこっちゃ?
  5. レイヤ実装 Layered Implementation

    システム要素をレイヤとし、各レイヤをスタックする。
    レイヤは抽象レベルによって分割されて、スタックの一番上が特定の操作等にあたり、 スタックの下にOSのシステムライブラリが来る。

    Note
    Tiered Computingとの違いはいまいちわからないが、単体でサービスを提供するかどうか、
    レイヤは機能の垂直分割、Tiered Computingは機能の水平分割の模様。
    所謂Web ApplicationのMVCのスタイルはTiered Computingにあたるんだろうか

    • メリット
      • レイヤの再利用
      • 関心ごとの分離
      • 各レイヤの分離による保守管理の用意さ
    • デメリット
      • 実装の柔軟性の低下
      • レイヤ毎に順番に開発する必要性がある
  6. パブリッシャ/サブスクライバ Publisher/Subscriber

    • メリット
      • SubscriberをPublisherの緩やかな結合
    • デメリット
      • 実装が複雑
      • 信頼性のあるメッセージ配信が必要な場合、複雑になりがち
  7. 非同期データ複製 Asynchronous Data Replication

    Publisher/Subscriberの変種。データを同期させる必要がある場合に利用される。
    データソース、データレプリカ、レプリケータの3つの要素で構成される

    Note
    DBのレプリケーションとかがこれにあたるのか

    • メリット
      • ロジックを複雑化させることなく、データが同期できる
    • デメリット
      • ソースとレプリカの更新の間で発生するタイムラグ
      • レプリカデータストアでの更新処理に対応すると複雑化する
  8. ディストリビューションツリー Distribution Tree

    パブリッシャ、ディストリビュータ、消費者の3つのタイプのシステム要素がある。
    パブリッシャがツリーの根になって、ディストリビュータが中間ノードを作り、消費者がツリーの葉になる。

    Note
    PubSubHubbubがまさにこれのような感じがする

    • メリット
      • 小規模から大規模まで拡張可能
    • デメリット
      • ディストリビュータを挟むので更新待ち時間がある
      • ディストリビュータが蓄えるキャッシュが規模の拡大に伴って負担になる
  9. 統合ハブ Integration Hub

    多数の異なるシステム間で情報を同期させる必要がある状況に利用される。
    非同期データ複製(Asynchronous Data Replication)を拡張したもの。

    データソース、データ送付先、ハブ、アダプタの4つのシステム要素がある。
    ハブを経由してデータソースとデータ送付先がデータを同期する。その際にアダプタがデータを共通形式に変換し、自由にデータを同期させられるよう責任をもつ

    • メリット
      • 新しいデータソースや送付先の追加による影響が少ない
      • アダプタによってソース独自の詳細等を隠蔽できる
    • デメリット
      • 全部の形式をサポートするのは現実的じゃないので、共通モデルの設計が難しい
      • 変換が多く挟まるので非効率的
      • ハブの作り込みが甘いと障害点になる
  10. タプルスペース Tuple Space

    クライアント(情報を生成して処理するコンピュータ処理要素)とタプルスペースそのもの(型づけされた情報タプルまたはレコードをクライアントが読み書きする記憶空間)の二つのタイプのシステム要素がある。
    クライアントとタプルスペースはクライアント/サーバネットワーク接続で接続する。クライアント同士は接続しない

    Note
    並列処理向きの模様。
    Job Queueもこれの一種?worker, clientがクライアント要素で、daemonがタプルスペースに当たるよね?

    • メリット
      • 単純なコンピュータ処理モデルを提供
      • クライアント間の緩やかな結合
    • デメリット
      • タプルスペースのスケーラビリティの限界

2011/03/05

Sapporo.js-2011.03.05の感想と本読み、LTのメモ

感想

  • 読み合わせのある勉強会は初めてだった
    • 読んで、その部分のコードを試してみんなで疑問を試したりして進んでいった
    • Perlでやるとしたら、どの本がいいのかな
    • さらっとやるのかと思ったら、意外と深いところまで突っ込んでた
  • 札幌市民ホールの会議室は綺麗でススキノにも近い
    • でも18, 24人のサイズの後は74人とかになる

以下、作業中のメモ

本読み

  • fibonacciのメモ化
  • Object.createprototype, constructorの挙動

    Object.create = function(o) {
        // 無名関数でもいいけど、名前を付けると
        // stacktraceで出ることもある
        var F = function Child() {};
        F.prototype = o;
        return new F();
    }
    
  • 関数と変数で同じ名前を使用したら、関数定義が先に解析されるので変数が上書きする

    // OK
    Object.create function(o) {
        alert(F);
        F.prototype = o;
        function F() {};
        return new F();
    }
     
     
    // NG
    Object.create function(o) {
        alert(F);
        F.prototype = o;
        var F = function F() {};
        return new F();
    }
    
  • __proto__を使うとnewを使わないでもいける。但しもじらだけっぽい

    var c = {}, p = {};
    p.__proto__ = { hoge: 'xxx' };
    c.__proto__ = p.__proto__;
    alert(c.hoge || 'ooo'); // mozilla => xxx, IE => ooo
    

LT @bad_at_mathさん

JavaScriptの成り立ち

  • Nescapeが1995
  • Scheme, Selfからの影響
  • ECMA(ヨーロッパ)で標準化
    • ECMA 262
    • ISOとかも
  • ECMA 262 - 3rd (1999年頃)
  • ECMA 262 - 4rd (2005年頃)
    • Class, Interface
    • MS/AdobeとYahoo/Mozillaが対立
    • ぐだぐだ
  • ECMA 262 - 5th (2009年頃)
  • ECMAの特徴
    • 小さい
  • ブラウザのJavaScript
    • CORE(ECMA)
      • SpiderMonkey
      • Rhino
      • V8
      • Carakan
      • Chakra
      • Appleのなんか
      • 第2次ブラウザ戦争
    • DOM
    • E4X
    • イベント系

Node.js

  • 以前からいろいろあったけど、使われてない
  • Multi Thread
    • IOが実行時間の中で支配的
    • context switchも数が多いとすごい
    • メモリいっぱい
  • Single Thread + Non Blocking IOか
    • 省メモリ
    • Node.jsはこっち

2011/03/03

Coro::LWPのリクエスト数をCoro::SemaphoreSetで管理

Coro::LWP

use Coro::LWPをするとLWPの諸々が勝手に上書きされるので非同期リクエストが可能になる

Coro::SemaphoreSet

Coro::SemaphoreSetで同時接続数の管理を行えば、相手のサーバから怒られたりしないし、自分のリソース管理も楽になるでしょう。

scheduleについて

join呼んだ方がいいのかは知らないけど、scheduleでやってみたかった
joinを使う場合はこんな感じ.

my @coros;
for ( 1 .. 10 ) {
    push @coros, async { ... };
}
$_->join for @coros;

scheduleを実行した場合、main threadに制御が帰ってこないので、semaphoreの値をチェックして、$Coro::main->readyでmain threadに戻してあげる必要があった

サンプルコード

2011/02/28

HTML::Shakanで文字化けしない方法

VERSION

関連モジュールのVERSIONは以下の通り
HTML::Shakan 0.09
Formvalidator::Lite 0.23

対処方法

先に現状での対処方法を書きます

HTML::ShakanのField定義はbinary stringsで行う

但し、この対処方法では以下の状態になる

  • $form->get_error_messagesはtext strings
  • $form->renderはbinary strings
  • use utf8しない状態なのが気持ち悪い

文字化けの原因

Shakanで使用するField定義データにtext stringsを使用すると、HTML生成時にbinary stringsと結合されるため文字化けが発生する

各モジュールの文字列の扱い

FormValidator::Lite

  • FV::L::Message::jaはuse utf8しているのでtext strings

HTML::Shakan

  • 内部でencode, decodeはしない
  • HTML生成時はbinary stringsとField定義データ、requestデータとの結合

希望の動作

  • Field定義はtext stringsで行いたい
  • $form->renderはtext stringsを返す
  • $form->get_error_messagesもtext stringsを返す

2011/02/27

perlbrewでinstallしたperlをquickrun.vimで使用する方法

解決 2011-11-05 16:58

再度調べたらさっくりと解決したので追記

shellにzshを使っているなら、.zshenvにperlbrewのsourceを設定するとよい

source $HOME/perl5/perlbrew/etc/bashrc


誰か教えてください!

とりあえず~/.vimrcに↓を書いてしのぐ
let g:quickrun_config={'perl': {'command': '/Users/yourname/perl5/perlbrew/perls/perl-5.12.2/bin/perl'}}

2011/02/26

[修正済み] Plack::Request + HTML::Shakan 0.08 or 0.09 + FormValidator::Lite 0.23の組み合わせで空のFileFieldを扱うとdieする

追記 2011/03/01
pull requestを送ったところmergeして頂きました。ありがとうございます!
FormValidator::Lite 0.24で修正されています
近いうちにCPANにもアップされるんじゃないでしょうか。


追記 2011/02/28
forkして治したけど、まだpull requestは送ってない
git://github.com/ysasaki/formvalidator-lite-perl.git



今日は眠いので明日に治すかもしれない

多分、以下の条件の場合にdieする

  1. FILE_*をconstraitに指定している
  2. Plack::Request使用
  3. FormValidator::Liteが0.23


Plack::RequestのparamまわりとFormValidator::Liteのファイル関連のconstraintのチェックタイミング、HTML::Shakanのuploadsの挙動あたりの問題っぽい。
Shakanだけ変更しても直せないかもしれない。

再現コード

2011/02/20

Hokkaido.pm #4のスライドと感想

Hokkaido.pm #4に参加しました。 参加者、ゲストのyusukebeさん、スタッフの皆様お疲れ様でした。

まずは今回の発表したスライドを貼っておきます。
CPAN/便利モジュール


View more presentations from aloelight.

反省会や懇親会等で聞いたこと等を忘れる前に書いておきます。

  • 会計は誤差がほとんどなかった
  • 反省会はスタッフっぽい人だけでなく、他の人も参加すべきではないか
  • 懇親会は終わった後そのままなだれ込める店が望ましい
    • #1はそうだった
    • 今の会場だと17時で閉まるので、やってる店が近くにない
    • 会場を移すべきか?
    • 金曜の夜にやるのも手(東京ではこれが多いらしい)
  • ハンズオンは思ったよりも人がくる
    • 高校生の彼はまたやって欲しいとか言ってた
    • ライブコーディングが見たい
    • 準備が大変なので何をやるか予め希望を取るとかしたほうがいいかも
  • 次回はスピーカーをやってくれそうな人がいる
  • 地元の人がそろそろ40分枠でやってみてもいいんじゃないか
  • 呼んでみたいゲストはまだまだ模様
    • JPAのゲストの派遣支援はかなり嬉しい
  • ustがピンクだった

2011/01/12

TeraTerm Menuからパスワード入力待ちでTeraTermを起動する方法

昨日ヘルプを読んで、初めて気がついたのでメモ
  1. TeraTerm Menuで通常通りにホスト名、ユーザ名、SSHの鍵を指定する
  2. 詳細設定をクリックして、オプションに/ask4passwdを追加
これでリストから起動するとパスワード以外が入力された状態になるので、
後はパスワードを入力してサーバにログインする