2010-10-30

[perl] AnyEvent::Twitter::Stream で自動再接続処理

Perl関係のツイートをリツイートするうざいボット @AE_PerlIsm を動かして得られた知見についての記事です。

キーワードを含んだツイートは、Twitter Streaming API を AnyEvent からいい感じで取得できる AnyEvent::Twitter::Stream で取得しているのですが、この接続が12~24時間に1回くらい切られるようなので、再接続処理が必要だと思います。

そのコードは以下のような感じでやっています。

注意点は、
接続状態から切れた時は wait なしで再接続する。
接続成功は、30秒おきに届く on_keepalive で判明する場合もある。
リトライウエイトで sleep を使うとイベントループが止まって良くないので、AE::timer を使う。

use AnyEvent::Twitter::Stream;

while (1) {
    my $done_cv = AE::cv;
    my $connected;
    my $streamer = AnyEvent::Twitter::Stream->new(
        method => 'filter',
        track => 'perl',
        # 認証は適当にやっとく

        timeout => 45,
        on_tweet => sub {
            $connected = 1 unless $connected;
            # 新しいツイートを受信したときの処理
        },
        on_keepalive => sub {
            $connected = 1 unless $connected;
        },
        on_error => sub {
            $done_cv->send;
        },
    );
    $done_cv->recv;
    undef $streamer;

    my $wait = $connected ? 0 : 2; #とりあえず2秒まってやる

    my $wait_cv = AE::cv;
    my $wait_t = AE::timer $wait, 0, $wait_cv;
    $wait_cv->recv;
}

2012/1/3 追記
現在の AE_PerlIsm は DotCloud にて、supervisord に依存して、接続が切れたら die で異常終了することで再接続するようにしてみました。再接続回数などの情報を保存して受け継ぐ必要がありますが、この方が簡単に書けると思います。