AnyEvent and Plack

21
AnyEvent Plack 2009 11 30 hiratara

description

AnyEventとPlackの社内勉強会用の資料。

Transcript of AnyEvent and Plack

Page 1: AnyEvent and Plack

AnyEvent と Plack2009年11月30日 hiratara

Page 2: AnyEvent and Plack

アジェンダ

AnyEvent ( ついでに Coro も )

PSGI と Plack

Page 3: AnyEvent and Plack

AnyEvent とは

非同期処理のインタフェースを定義したもの

裏でイベントループが回っていることを想定(イベントループは普通シングルスレッド)

Page 4: AnyEvent and Plack

イベントループとは?

イベントを監視するループ。GUIでよく見られる

プログラマは、イベントに対応する処理を書く

イベントループがイベントに紐づく処理を呼び出すことで、プログラムの処理が進む

Page 5: AnyEvent and Plack

Perlの主なイベントループ

EV

Event

Glib

Tk

Perl

Event::Lib

Irssi

rxvt-unicode

IO::Async

Qt

POE

APIが全然違う

Page 6: AnyEvent and Plack

AnyEventの使い方use strict; use warnings;use AnyEvent;

my $done = AE::cv;

my $t1; $t1 = AE::timer 5, 0, sub { print "Waited 5 sec", "\n"; undef $t1; $done->send;};

$done->recv;

Page 7: AnyEvent and Plack

AnyEventの使い方

AE::cv → メインループを回して、計算させる

recv : 計算が終わるまでメインループを回す

send : 計算結果をrecvに返す

Page 8: AnyEvent and Plack

AnyEventの使い方

基本的に、イベント発生時のコールバックを渡す

(JavaScriptに似ている)

AE::timer : 一定時間経った後に呼び出すcb

AE::io : 入出力が終わった時に呼び出すcb

Page 9: AnyEvent and Plack

AnyEventと非同期処理

コールバック待ち時も、イベントループは回っている→ 非同期処理が可能

例: http://hogehoge.com/ のコールバックを待ちつつ  http://foofoo.com/ の読み込みを開始できる

Page 10: AnyEvent and Plack

Coroとは?

Perlの1プロセッサでのスレッド(コンテキストスイッチ)

スレッドの切り替えは、明示的に行う(schedule や cede などのメソッドで切り替わる)

Page 11: AnyEvent and Plack

Coroの使い方use strict; use warnings;use Coro;use Coro::Timer;

async { Coro::Timer::sleep 5; print "Waited 5sec", "\n"; $Coro::main->ready;};

schedule;

Page 12: AnyEvent and Plack

Coroの使い方

schedule : 別スレッドに処理を移す (このスレッドは眠る)

ready : 眠ってるスレッドを起こす

陰でこっそり schedule と ready をやってくれる物も例 :

Coro::Timer::sleep (scheduleし、一定時間後にready)

Page 13: AnyEvent and Plack

CoroとAnyEvent

CoroとAnyEventはセットで話されることが多い

理由: Coro は AnyEventを使っている

こっそりと schedule と ready する処理

裏スレッドでイベントループを回し、コールバックでreadyさせている

Page 14: AnyEvent and Plack

PSGI

Perl の WSGI や Rack

WEBサーバ と Perl のインタフェースを定めたもの

WEBサーバ PerlのコードPSGI

Page 15: AnyEvent and Plack

PSGI

Plack::Server::CGI PerlのコードPSGIApache

CGI

mod_perl

Plack::Server::Apache2

Apache + mod_psgi

PSGI

PSGIlighttpd

Plack::Server::Standalone

PSGI

Page 16: AnyEvent and Plack

PSGIでHello World

use strict;use warnings;

sub { my $env = shift; return [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ] ];};

Page 17: AnyEvent and Plack

Middleware

package XHeader;use strict;use warnings;use base Exporter::;our @EXPORT = qw/xheader/;

# xheader is a middleware to wrap $appsub xheader { my $app = shift; sub { my $env = shift; my $res = $app->($env); push @{$res->[1]}, 'X-PSGI-Used' => 1; return $res; };}

PSGIアプリケーションを変換

Page 18: AnyEvent and Plack

Plackとは

PSGI仕様のリファレンス実装(お手本となる実装のこと)

PSGIサーバの実装

PSGI準拠アプリのためのツール群

Page 19: AnyEvent and Plack

Plack

Plack::Server::CGI

PerlのコードPSGI

Plack::Server::Apache2

Plack::Server::Standalone

Plack::Server::AnyEvent

Plack::Server::Coro

Plack::Request

CGI::PSGI

CGI::Emulate::PSGI

Plack::Middleware::XXX

Plack::App::URLMap

Plack::App::Builder

plackup

Page 20: AnyEvent and Plack

psgi.streaming

PSGIの仕様。非同期にレスポンスを返すのに用いる

sub { my $env = shift; $env->{'psgi.streaming'} or die;

return sub { my $respond = shift; $respond->([ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ], ]); };};

Page 21: AnyEvent and Plack

そして Tatsumaki へ

Plack AnyEvent

TatsumakiPlack::Server::AnyEvent

Plack::Server::Coro

PSGIYour Application

AnyEvent

AnyEvent

Coro