新規作成
OpenIDで認証してエントリーを新規作成します
共有
エントリーにはOpenIDで閲覧と編集に制限かけることができます
変更履歴
編集履歴もあるので、コラボレーションにも活用できます

Coro::LWPでtimeout + timeoutきりかえ

Coro::LWPでタイムアウトさせるに加えて、1つのasyncの中で複数回LWPを行ない、それぞれのtimeout、on_destory時の挙動を変更するtest


何がやりたいかというと

A->B->C

というリクエスと順は保ちつつ、それぞれを非同期でアクセスするものです

proxyっぽいものを実装する際に、Aで認証、Bで実際のアクセス、Cでフィルタ動作

を狙ってます。

use Time::HiRes;
use Coro;
use Coro::LWP;
use LWP::UserAgent;
use Data::Dumper;

sub coro_timeout {
    my $timeout = shift;
    my $cb = shift;
    my $coro = $Coro::current;
    $coro->{timeout_at} = Time::HiRes::time() + $timeout;
    my $installed_destroy = $coro->{on_destroy_once} ? 1 : 0;
    $coro->{on_destroy_once} = $cb;
    if ( !$installed_destroy ) {
        $coro->on_destroy( sub {
            my $message = shift;
            my $cb = delete $coro->{on_destroy_once};
            return unless $cb;
            return if $message ne 'timeout';
            $cb->($message);
        });
    }
}

my $parent_loop = 0;
for my $timelimits ( [10,10,10],[1,10,10],[10,1,10],[10,10,1] ) {
    $parent_loop++;
    my $parentloop = $parent_loop;
    async {
        $Coro::current->desc("LWP");
        my $childloop = 0;
        for my $timelimit ( @$timelimits ) {
            $childloop++;
            my $ua = LWP::UserAgent->new;
            coro_timeout($timelimit, sub {
                 my $message = shift;
                 warn sprintf "parent: %s, child: %s cancel because %s", $parentloop, $childloop, $message;
            });
            my $res = $ua->get("http://localhost/tmp/sleep3.cgi");
            warn "parent: $parentloop, child: $childloop done!";
        }
        warn "parent: $parentloop done all!";
    };
}

my $w; $w = AnyEvent->timer (
    after => 0.5,
    interval => 1,
    cb => sub {
        my $now = Time::HiRes::time;
        my @lwp_coro = grep { $_->desc eq "LWP" } Coro::State::list;
        for my $coro (@lwp_coro) {
            if ($now > $coro->{timeout_at}) {
                $coro->cancel("timeout");
            }
        }
        if (@lwp_coro == 0) {
            exit;
        }
    }
);

schedule;

実行結果

% perl coro_lwp.pl
parent: 2, child: 1 cancel because timeout at coro_lwp.pl line 41.
parent: 4, child: 1 done! at coro_lwp.pl line 44.
parent: 3, child: 1 done! at coro_lwp.pl line 44.
parent: 1, child: 1 done! at coro_lwp.pl line 44.
parent: 3, child: 2 cancel because timeout at coro_lwp.pl line 41.
parent: 4, child: 2 done! at coro_lwp.pl line 44.
parent: 1, child: 2 done! at coro_lwp.pl line 44.
parent: 4, child: 3 cancel because timeout at coro_lwp.pl line 41.
parent: 1, child: 3 done! at coro_lwp.pl line 44.
parent: 1 done all! at coro_lwp.pl line 46.
created by blog.nomadscafe.jp

mobstrikeに於けるファミリーの追加規則

モブストライク( http://mfga.jp/ )に於ける、ファミリの追加規則等について。

MobStrike登録可能アカウントについて

※ログイン画面に表示されるAOLmailとAIMは同じAOL Accountによって機能する物であるので、同様の物と判断し、AOLMailに統一した。

MobStrike参加前

mixi
登録録する時のマイミクシィの中のMobStrike参加者分のファミリ数となる。
twitter
登録する時のフォローしている最新から100人目迄の人の中からMobStrike参加者が居るとその人数分のファミリ数となる。
各種メール
登録する時の相互アドレス登録しているMobStrike参加者分のファミリ数となる。

MobStrike参加後

mixi
登録録する時のマイミクシィの中の誰かがMobStrikeに参加するとファミリが増える。
twitter
登録する時のフォローしている最新から100人目迄の人の中からMobStrikeに参加するとファミリが増える。
各種メール
登録する時の相互アドレス登録の中の誰かがMobStrikeに参加するとファミリが増える。

新たにファミリを増やしたい場合

  • ファミリーにて取得出来るURLから登録して貰うと各種条件に関わらずファミリが1増える。
  • ボスにリワードポイント20ポイントを払ってファミリーを2×n人追加出来る。

ポイント

  • 初期ファミリ数や随時追加ファミリ数は登録時のフォロワやマイミクシィなどの相互登録の数による固定数である事。
  • twitterはAPIに取得制限があるため、登録時の最新フォロワの100人目までしか取れない為、フォローしまくってフォローして貰いやすくするという方法によって妨害か可能である事。
  • mixiや各種メールは取得の制限が無い為、幾らでも増やせる事。

参考資料

モブストライク初心者マニュアル

Twitter/Search #mbst

注意

尚、結構な情報が推測した物なので間違っていたらコメントや編集などをして頂けると幸いです。

又、加筆修正は随時受け付けております。

created by juner.net

AnyEvent::MPRPCでMessagePack RPC

MessagePack RPCは全てのメッセージにシーケンス番号をいれることで、1つのTCP接続でpipeliningのような遅延リターンができる。

Gearmanでやりたかったいめーじはこちらのほうがちかい。


server側

use AnyEvent;
use AnyEvent::MPRPC::Server;


my $server = AnyEvent::MPRPC::Server->new( port => 4423 );
$server->reg_cb(
    'sleep' => sub {
        my ( $res_cv, $sleep ) = @_;
        warn $sleep;
        my $t; $t = AE::timer $sleep, 0 , sub {
                undef $t;
                $res_cv->result("$sleep done!");
            };
    },
);

AE::cv->recv;

client側

my $work_count = 0;
my @sleeps = qw/1 5 2 4 3 2 1/;
my $worked = 0;

my $client = AnyEvent::MPRPC::Client->new(
    host => '127.0.0.1',
    port => 4423,
);

for my $sleep ( @sleeps ) {
    my $n = $work_count++;
    $client->call( 'sleep' => $sleep )->cb( sub {
        my $res = shift->recv;
        warn "$n: $sleep: $res";
        $worked++;
    });
};

my $w; $w = AnyEvent->timer(
    after    => 0,
    interval => 1,
    cb       => sub {
        if ($worked ==  @sleeps) {
            exit;
        }
    }
);

AE::cv->recv;

実行結果

% perl anyevent_mprpc_client.pl0: 1: 1 done! at anyevent_mprpc_client.pl line 20.
6: 1: 1 done! at anyevent_mprpc_client.pl line 20.
2: 2: 2 done! at anyevent_mprpc_client.pl line 20.
5: 2: 2 done! at anyevent_mprpc_client.pl line 20.
4: 3: 3 done! at anyevent_mprpc_client.pl line 20.
3: 4: 4 done! at anyevent_mprpc_client.pl line 20.
1: 5: 5 done! at anyevent_mprpc_client.pl line 20.
created by blog.nomadscafe.jp

AnyEvent::Gearman::Worker

ちょっと勘違いしていた。pipeliningのようなことができるわけじゃないから、1つの接続で

非同期に処理をしてくれるわけじゃない。


これは結果、普通のworkerとほぼ同じになる

use AnyEvent::Gearman::Worker;

my $worker = AnyEvent::Gearman::Worker->new(
    job_servers => ['127.0.0.1:4730'],
);
$worker->register_function(
    'sleep' => sub {
        my $job = shift;
        my $sleep = $job->workload;
        warn $sleep;
        my $t; $t = AnyEvent->timer(
            after => $sleep,
            cb    => sub {
                warn "$sleep done!";
                undef $t;
                $job->complete("$sleep done!");
            }
        );
    }
);
AE::cv->recv;

非同期/パラレルを狙うならこうする(力技

my @workers;
for ( 1 .. 4 ) {
    my $worker =
      AnyEvent::Gearman::Worker->new( job_servers => ['127.0.0.1:4730'], );
    push @workers, $worker;
    $worker->register_function(
        'sleep' => sub {
            my $job   = shift;
            my $sleep = $job->workload;
            warn $sleep;
            my $t;
            $t = AnyEvent->timer(
                after => $sleep,
                cb    => sub {
                    warn "$sleep done!";
                    undef $t;
                    $job->complete("$sleep done!");
                }
            );
        }
    );
}

AE::cv->recv;
created by blog.nomadscafe.jp

PlackでproxyをCoroで

PlackでproxyをCoroで

use Plack::Request;
use HTTP::Request;
use Data::Dumper;
use Coro;
use Coro::AnyEvent;
use Coro::LWP;
use LWP::UserAgent;

my $hanlder = sub {
    my $env = shift;
    my $req = Plack::Request->new($env);
    
    my $cv = AE::cv;
    async_pool {
 
       my $request = HTTP::Request->new(
            $req->method,
            $req->request_uri,
            $req->headers,
            $req->raw_body
        );

        for ( qw/Connection Keep-Alive Proxy-Authenticate Proxy-Authorization
               TE Trailers Transfer-Encoding Upgrade Proxy-Connection Public/ ) {
            $req->headers->remove_header($_);
        }
        $req->headers->scan(sub {
            my ( $k, $v ) = @_;
            if( $k =~ /^Client-/ ) {
                $headers->remove_header($k);
            }
        });
        my $ua = LWP::UserAgent->new;
        my $res = $ua->request($request);
        my @res_header;
        $res->headers->scan(sub{
            push @res_header, @_;
        });
        $cv->send([
            $res->code,
            \@res_header,
            [$res->content]
        ]);
    };

    return sub {
        my $start_response = shift;
        $cv->cb(
            sub {
                $start_response->( shift->recv );
            }
        );
    };
}
created by blog.nomadscafe.jp

Plack/PSGIで非同期WebServerをCoroで

PSGI/Plackで非同期 Web ServerをCoroで

use Plack::Request;
use HTTP::Request;
use Data::Dumper;
use Coro;
use Coro::AnyEvent;
use Coro::LWP;
use LWP::UserAgent;

my $hanlder = sub {
    my $env = shift;
    my $req = Plack::Request->new($env);
    
    my $cv = AE::cv;
    async_pool {
        my $request = HTTP::Request->new(
            $req->method,
            URI->new_abs($req->request_uri,'http://localhost/'),
            $req->headers,
            $req->raw_body
        );
        my $ua = LWP::UserAgent->new;
        my $res = $ua->request($request);
        my @res_header;
        $res->headers->scan(sub{
            push @res_header, @_;
        });
        $cv->send([
            $res->code,
            \@res_header,
            [$res->content]
        ]);
    };
    return sub {
        my $start_response = shift;
        $cv->cb(
            sub {
                $start_response->( shift->recv );
            }
        );
    };
}
created by blog.nomadscafe.jp

Plackでproxy

lestrratさんもつくっているみたい

use Plack::Request;
use HTTP::Request;
use Data::Dumper;
use AnyEvent;
use AnyEvent::HTTP;

my $hanlder = sub {
    my $env = shift;
    my $req = Plack::Request->new($env);
    
    #HTTP::Proxyからコピー
    for ( qw/Connection Keep-Alive Proxy-Authenticate Proxy-Authorization
          TE Trailers Transfer-Encoding Upgrade Proxy-Connection Public/ ) {
        $req->headers->remove_header($_);
    }
    $req->headers->scan(sub {
        my ( $k, $v ) = @_;
        if( $k =~ /^Client-/ ) {
            $headers->remove_header($k);
        }
    });
  
    my $cv = AE::cv;
    AnyEvent::HTTP::http_request $req->method, $req->request_uri,
        timeout => 30,
        headers => $req->headers,
        body    => $req->raw_body,
        sub {
            my ( $body, $header ) = @_;
            warn Dumper($header);
            $cv->send( [$header->{Status}, [ %$header ], [$body]] );
        };

    return sub {
        my $start_response = shift;
        $cv->cb(
            sub {
                $start_response->( shift->recv );
            }
        );
    };
}

起動

$ plackup --app proxy.psgi --server AnyEvent --port 8080

curlでためす

$ curl  -v -x http://localhost:8080 http://blog.nomadscafe.jp/
created by blog.nomadscafe.jp

mobstrikeに於ける各マフィアの区別方法

マフィアの分類とか

モブストライク( http://mfga.jp/ )に於ける、マフィアの区分方法について。

仕事や戦績の傾向による分類

サラリーマンマフィア
仕事成功回数が勝利数を超える場合
戦闘民族
勝利数が仕事成功回数を超える場合

戦闘民族についての追記

戦闘民族毎のさらなる分類方法についての云々

戦闘民族のランク測定方法
勝利数/仕事成功回数
エリート戦闘民族
戦闘民族ランクが2以上
初級エリート戦闘民族
戦闘民族ランクが3以上
中級エリート戦闘民族
戦闘民族ランクが6以上
上級エリート戦闘民族
戦闘民族ランクが10以上

パラメータによる分類

バランス
攻撃も防御もそれなりにこなすマフィア。特化マフィアよりファミリー数の大小によるアドバンテージが強く発生するが、それゆえ行き詰ることも#
バキュラ
ポイントをすべて防御に振っている鉄壁マフィア。とはいえこの戦略をとるマフィアは他人よりファミリー数が多い傾向があり、返り討ちにあった挙句、そこから殴り返されることも多い地雷である。しかし甲羅を叩き割れれば美味#
プレデター
ポイントをすべて攻撃に振っている肉食系マフィア。防御は捨てていることが多く、敗北した数以上に殴り返せればそれでよいと思っている。スタミナも多いのでうかつに手を出すと連撃を浴びることもある#
ブラスター
ポイントの多くをスタミナに振っている連撃マフィア。だが、この方法を使うためにはどうやっても攻撃力をどこからか調達する必要があり、威力不足になると自分から火に飛び込む目になる諸刃の剣…!
全裸マフィア
防御力10以下のマフィア#
絶倫
体力特化#
フリーハグ
攻撃特化#
おさわり禁止
防禦特化#

隠語

挨拶
2回同じ人を抗争すること。#
シネ
2回同じ人を抗争すること。#
スキダ
3回同じ人を抗争すること。#
おはよう
朝方に4回同じ人と抗争すること。#
アイシテル
5回同じ人を抗争すること。#
南無阿弥陀仏!
7回同じ人を抗争すること。#
キョウモアイシテル
7回同じ人を抗争すること。#
おはようございます
朝方に9回同じ人を抗争すること。#
礼砲
21回同じ人と抗争すること。##
ありがとう(サンキュー)
39回同じ人と抗争すること。#
created by juner.net

Perl who's who

mst

  • maintainer of Catalyst
  • Devel::Declare

ingy

  • author of Spiffy, Inline, YAML, Test::Base, etc.

mschwern

  • author of E::MM, Class::Accessor, etc.

nothingmuch = nuffin = yuval

  • Data::Visitor
  • Catalyst::Session, Cat::Auth, etc.
  • current maintainer of Moose

obra = jesse

  • purple hair
  • kindle hack
  • loves small PC
  • author of Jifty, RT, H::S::S, SD, etc.
  • best practical

clkao

  • author of SVK
  • best practical

Sartak = Shawn

  • YAPC::Asia 2009
  • author of Mo*u*se
  • Best practical
  • loves MooseX::Declare

rafl = florian

  • maintainer of Devel::Declare
  • maintainer of Catalyst

Stevan

  • author of Moose

Dave Rolsky = autarch

  • author of DateTime
  • maintainer of Moose

sri

  • author of Catalyst
  • author of Mojo

rcaputo

  • author of POE

mlehmann = schmorp

  • linux hacker
  • committer of gcc
  • author of JSON::XS, AnyEvent, Coro, etc.
  • SEE ALSO

adamk = alias

  • maintainer of Module::Install, DBD:SQLite
  • author of *::Tiny
  • maintainer of http://svn.alia.as/
  • comitter of Padre

andk != adamk

  • CPAN Testers
  • good bug reporter
  • author of CPAN

Larry Wall = TimToady

  • author of Perl

miyagawa = tatsuhiko != 宮川康彦

  • author of Sledge, Plagger, Plack, etc.
  • white camel award

kappa

  • Russian blog
created by anonymous

使用目的がわからないAA

   ∧_∧   \      J( 'ー`)し          /
   ( ・ω・)    \ バリバリC□l丶l丶       /    ∧_∧
   (っ囗と) バリバリ \    /  (   )やめて!/    ( ゚ω゚ ) 支払いは任せろー
   ./   )       \  (ノ ̄と、 i    / バリバリC□ l丶l丶
   ( / ̄∪    __ lヽ,,lヽ   ∧∧∧∧  /       /  (    ) やめて!
    _|. ::|_      | |Θ|(    ) <   マ >        (ノ ̄と、   i
| ̄ ̄ ̄| ̄ ̄|_ |_|_|と    i. <   ジ >            しーJ
|___|__|_|  |_|  しーJ < 財 ッ >         
—————————————< 布 ク >———————————————————
                    < の テ >\      /^`''-..,
  「バリバリ〜〜♪」     /< 予  l  >.  \    //  /`〉゙'.,
    /■\   /■\  / < 感 プ >   .\ //  / / ;;::|
   .( ´∀`)  ( ´∀`)/   <  !!! 式 >     //  / / ;;:::/
  ⊂    つ⊂   /     <     >     ヤ,\/ / ;;::/
   .人  Y   人/         ∨∨∨∨      ヤ, V/ ;;::/ ミ バリバリ
   し'(_)   /  乗せてやんよ!  .,... -—————ヤ, //7::/  ___
                     ,,..-''"(´・ω・`)     ヤ,/_;;:::/ヽ、\皿#,,\
              ,,.. - ''"゙゙;>ー—---——;=''''"゛゛⌒ヽ, ̄ィ7  /〉  ''´ ̄`i マジック
            ,,. '"  ,,. '"        /    /   ヽェソ 乃▲ /,r'⌒!'  テープ式!?
          ∠二フ/___,___/∠二フ/  r'⌒ヽヽ_/´   // ∩ i    lヽ,,lヽ
         〔`゙`ー—————————'''''"゙´   / ∩ |   ̄___!/ノ ∪ノ   (    )
          〉同〉—— [二二] ———j同>=:;つ_ノ ∪ノ/ ̄   `ー—''´    と   i
           ̄ ̄ー— ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  `ー—''´               しーJ
created by https://id.mixi.jp/mrmt

<12345678910>