Danga::Socketの非同期処理の仕組みとPerlbalで非同期処理するプラグインを書く方法

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    1 Favorite

    Danga::Socketの非同期処理の仕組みとPerlbalで非同期処理するプラグインを書く方法 - Presentation Transcript

    1. YAPC::Asia 2009 Tokyo 2009/9/10 宮下 剛輔
    2. 自己紹介
      • 宮下 剛輔( mizzy )
      • ペパボで技術責任者というのをやってます
      • Perl 界一の子だくさん?
        • 11 月に 4 人目が生まれる予定です
    3.  
    4.  
    5. アジェンダ
      • イベント駆動型プログラミングによる非同期処理
      • Danga::Socket の非同期処理の仕組み
      • Perlbal の動作概要
      • Perlbal プラグインでの非同期処理
      • まとめ
    6.  
    7. イベント駆動型プログラミング
      • イベントを待機し、起こったイベントに従って処理を行うプログラミングパラダイム
      • フロー型プログラミングに対する概念
    8. イベントの種類
      • I/O
        • I/O の読込可能 / 書込可能状態でイベント発生
      • タイマー
        • 一定時間後にイベント発生
      • シグナル
        • シグナル受信時にイベント発生
      • 子プロセス
        • 子プロセス終了時にイベント発生
    9. メインループ
      • イベント駆動型プログラミングは、「イベント処理登録」 -> 「メインループ突入」という流れ
      • イベントループとも呼ばれる
      • イベント発生の有無をループする度に確認し、発生したイベントに応じた処理を行う
      • イベント処理後ループに戻り、次にイベント発生するまでループを繰り返す
      • このような流れで非同期に処理を行う
    10. メインループの例 タイマー処理 I/O イベント待ち I/O イベント処理 ポストメインループ処理
    11.  
    12. Danga::Socket が対応してるイベント
      • I/O イベント
      • タイマーイベント
    13. I/O イベント処理
      • Danga::Socket では以下の I/O 多重化機構に対応している
        • kqueue
        • epoll
        • poll
      • 適切な I/O 多重化機構を自動で選択してくれる
    14. epoll の例
      • use Sys::Syscall
      • $epfd = epoll_create (1024);
      • epoll_ctl ( $epfd , EPOLL_CTL_ADD, $fd , EPOLLIN|EPOLLOUT);
      • while (1) { # ここからイベントループ
      • epoll_wait ( $epfd , 1024, $timeout, @events );
      • for $event ( @events ) {
      • # イベントに応じた処理
      • }
      • }
    15. Danga::Socket での I/O イベント登録
      • use base ‘Danga::Socket’;
      • sub new {
      • # ファイルディスクリプタを new に渡す
      • $self->SUPER::new( $fd );
      • }
      • sub event_read {
      • # $fd が読込可能になった時に実行
      • }
      • sub event_write {
      • # $fd が書込可能になった時に実行
      • }
    16. Danga::Socket での I/O イベント登録 その 2
      • Danga::Socket->AddOtherFds(
      • $fd => sub {
      • # read イベントでの処理
      • },
      • );
    17. Danga::Socket での I/O イベント登録 その 3
      • Danga::Socket::Callback->new(
      • handle => $fd ,
      • on_read_ready => sub {
      • # read イベント処理
      • },
      • on_write_ready => sub {
      • # write イベント処理
      • },
      • );
    18. Danga::Socket でのタイマーイベント登録
      • Danga::Socket->AddTimer(
      • 10,
      • sub {
      • # 10 秒後に実行される処理
      • },
      • }
    19. Danga::Socket でのメインループの開始
      • Danga::Socket->EventLoop();
    20. メインループ処理のおさらい タイマー処理 I/O イベント待ち I/O イベント処理 ポストイメインループ処理
    21.  
    22. Perlbal の動作(リバースプロキシとして利用の場合) BackendHTTP ClientProxy TCPListener Client Server ClientProxy Client BackendHTTP Danga::Socket ベースの オブジェクト
    23. Perlbal プラグインの動作 (start_proxy_request フック) BackendHTTP ClientProxy TCPListener Client Server Plugin::Hoge 今回のターゲット
    24.  
    25. 対象となるフック
      • start_proxy_request フックでの実行を前提として解説していきます
    26. 同期処理プラグインの場合 ClientProxy TCPListener Client Server Plugin::Sync Client
    27. 非同期処理プラグインの場合 ClientProxy TCPListener Client Server Plugin::Async Client ClientProxy
    28. プラグインを非同期にするには?
      • プラグインの処理を Danga::Socket のイベントループに組み込む
        • Danga::Socket ベースのクラスを作成
        • または Danga::Socket::Callback を利用して処理を書く
        • Danga::Socket::AddTimer でタイマー処理しても OK
        • 利用するライブラリにも注意
          • ブロックしないライブラリを使う
          • どうしてもブロックしてしまう処理は、 Gearman::Client::Async で外出し
    29. プラグインを非同期にするには?
      • 非同期処理が完了したら、次のフェーズに処理を移す
        • プラグインのコールバックを利用
        • Perlbal 本体の修正も必要
    30. 非同期処理するクラス
      • package My::Drizzle ;
      • use base ‘Danga::Socket’ ;
      • use Net::Drizzle ':constants' ;
      • sub new {
      • $self->SUPER::new($fh);
      • $self->watch_read(1);
      • }
      • sub event_read {
      • # DB リクエスト状態確認と完了時のコールバック処理
      • }
    31. 注意
      • Danga::Socket::Callback をつかっても OK
      • AddOtherFds は使えない
        • AddOtherFds で登録されたファイルディスクリプタは、イベントループ突入の最初にしか EPOLL_CTL_ADD や EV_ADD されない
      • 直接 epoll_ctl とか呼び出してもいいけど、ポータビリティは低い
    32. プラグイン register 処理
      • package Perlbal::Plugin::AsyncDb ;
      • sub register {
      • my ( $class, $svc ) = @_;
      • $svc->register_hook(
      • 'Async' => 'start_proxy_request',
      • &request_db ,
      • );
      • return 1;
      • }
    33. 非同期処理クラスの呼び出し
      • sub request_db {
      • my Perlbal::ClientProxy $client = shift ;
      • My::Drizzle->new(
      • callback => sub {
      • # 完了時のコールバック処理
      • },
      • );
      • return 1; # 超重要ポイント!
      • }
    34. return 0 の場合 BackendHTTP ClientProxy TCPListener Client Server Plugin::Async Plugin::Async の処理が 終わらないのに次の処理へ
    35. return 1 &コールバック処理 BackendHTTP ClientProxy TCPListener Client Plugin::Async 処理を終了して イベントループへ Server return 1 コールバック
    36. コールバックで必要な処理
      • ClientProxy の処理が handle_request() の途中で終了してイベントループに戻っている
      • プラグインの処理が完了したら、 ClientProxy の次の処理から再開
      • 停止してるのは、 handle_request() 中の以下のコード
      • return if $svc->run_hook(
      • 'start_proxy_request', $self
      • );
      • この次から処理を再開するようにする
    37. コールバック処理
      • my Perlbal::ClientProxy
      • $client = shift ;
      • My::Drizzle->new(
      • callback => sub {
      • $client->{async_complete} = 1;
      • $client->handle_request;
      • },
      • );
    38. ClientProxy::handle_request の修正
      • - return if $svc->run_hook(
      • - 'start_proxy_request', $self
      • - );
      • + unless ( $self->{async_complete} ) {
      • + return if $svc->run_hook(
      • + 'start_proxy_request', $self
      • + );
      • + }
      • + $self->{async_complete} = 0;
    39.  
    40. 非同期処理プラグインを書くポイント
      • 非同期にしたい処理は Danga::Socket のイベントループにつっこむ
      • プラグイン処理が呼び出されたら return 1
      • プラグイン処理が完了したら、コールバックで処理を再開してやる
      • Perlbal 本体の修正も必要
      • プラグインの実行順にも注意
        • return 1 するとそれ以降の同じフックのプラグインは実行されない
    41.  

    + mizzymizzy, 2 months ago

    custom

    667 views, 1 favs, 1 embeds more stats

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 667
      • 666 on SlideShare
      • 1 from embeds
    • Comments 0
    • Favorites 1
    • Downloads 0
    Most viewed embeds
    • 1 views on http://hiroki.jp

    more

    All embeds
    • 1 views on http://hiroki.jp

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories