SlideShare ist ein Scribd-Unternehmen logo
1 von 21
Downloaden Sie, um offline zu lesen
em-synchrony について

    2011年8月6日
        cuzic
自己紹介                  1
  cuzic といいます
    きゅーじっく      と読みます
 Ruby 暦は かれこれもう10年くらい
 近況
    Nook Simple Touch というデバイスを買いました
    Android 2.1 が動く、ディスプレイが e-ink の端末
    定期巡回している Web 記事を快適に読めてしあわせ
 今後の勉強会予定
    8月20日(土) Coders At Work 読書会 #2
       今回と同じ会場です
       2週間後!
       みんな来てください。




Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
今日の議題                 2
            • 複数処理の同時並行実行について
            • マルチスレッドによる同時並行処理
従来の
            • IO多重化 による同時並行処理
並列処理


            • eventmachine とは
 event-     • コールバック登録による非同期処理
machine


            • Fiber とは
   em-      • 非同期処理の逐次処理的な記述
synchrony



Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
同時並行で処理を進めて高速化したい!                       3
  過剰な待ち時間のために、動作が遅かったりします
     例) WEBダウンロード
        ネットワークIO の待ち時間の間は CPU は働きません
        CPU としては軽い処理なのに、もったいない!
   ⇒ 多数の URL からのダウンロードであれば、同時並行で
    ダウンロードさせれば、高速化可能。
  同時に処理させる方法の例
     マルチスレッド
        スレッド特有の問題が多数存在
        (排他制御、デッドロック、変数の同期 etc)
     IO 多重化(select(2) の利用など)
        状態の管理が大変。慣れるまでは苦労する。
     マルチプロセス
        今回は説明しません



Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
マルチスレッドによる同時並行処理                                    4
マルチスレッドの長所                     require 'open-uri'

   書きやすい                       urls = %W[http://localhost:3000/1
   同期処理的に書ける                        http://localhost:3000/2 ]
                               urls.each do |url|
   (Ruby の場合は)                   puts "#{url} #{open(url).read}"
   自動的にIO 多重化を                 end
   いいかんじにできる
   (Ruby の場合)たいてい、
   マルチスレッドで十分!                 require 'open-uri'
マルチスレッドの短所
                               urls = %W[http://localhost:3000/1
   スレッド特有の多々の問題                         http://localhost:3000/2]
      排他制御                     threads = urls.map do |url|
                                 Thread.start(url) do |url|
      デッドロック                       body = open(url).read
      たまに起きる不可解なバグ                 puts "#{uri} #{body}"
   スレッド切り替えが遅い                   end
                               end
      コンテキスト切替が必要
   いつ何が動作している不明                threads.each{|t| t.join}
Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
IO多重化 による同時並行処理                                 5
IO多重化の長所                             AsyncHTTPClient の作成

   動きがすばやい                             巡回したい URL と、
                                      読み込み後にしたい処理
   スレッド特有の各種問題に                        (コールバック)を登録
   悩まされない
                                       HTTP 取得処理を実行
IO多重化の短所                              取得終了後、登録していた
   慣れるまで書きにくい                          コールバックを呼び出し
      逐次的に処理を書けない
      慣れが必要
                             sockets = ソケット作成処理(urls)
      状態遷移を管理したり、
                             loop do
      コールバックの登録が               readables, = IO.select sockets
      常套手段                       readables.each do |s|
  select(2) を使うプログラム               バッファ = s.read_nonblock 65536
                                   sockets.delete s if s.eof?
  を書くのは結構大変                      end
 ⇒ そういうときには                    end
   eventmachine                break if sockets.empty?
                             end
                             登録していたコールバック呼び出し
Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
これからの説明                                     6
                         eventmachine          em-http-request
 eventmachine
                         標準の HTTP                  による
     とは
                          クライアント               HTTPクライアント



                         Fiber を使った             em-synchrony
   Fiber とは              非同期処理の                   を使った
                          逐次的記述                  逐次的記述



EM::Iterator の          EM::Synchrony::
コールバックによ                 Iteratorによる           その他 落穂拾い
   る記述                    逐次的記述

Ruby/Rails勉強会@関西 第50回    「em-synchrony について」
eventmachine とは                         7
非常に有名なノンブロッキングIO を実現するライブラリ
   Heroku 、 Github、 EngineYard などで利用されている
広範なプロトコルに対応
   HTTP、SMTP、MySQL 、PostgreSQL、Memcached、Redis
内部的には select(2) による IO 多重化を実現
   環境次第では、epoll 、kqueue なども利用可能
      非常にスケーラブルな IO 多重化が可能
読み込み処理終了などの”イベント”に対応した処理を記述
   返り値は使わず、コールバックを登録する
   コールバックの中は、処理完了後に実行される

 ret1 = 処理1(引数)                         処理1(引数) do |ret|
 ret2 = 処理2(ret1)                         処理2(ret1) do |ret2|
 その後の処理                                     その後の処理
                                          end
                                        end
Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
サーバーサイドのスクリプト                                   8
  sinatra/async                require   'rubygems'
                               require   'sinatra'
     WEBフレームワーク                require   'sinatra/base'
     Sinatra の非同期 版            require   'sinatra/async'
                               require   'eventmachine'
     aget が get の非同期 版
  仕様                           class Delayed < Sinatra::Base
                                 register Sinatra::Async
     /1 と /2 に応答を返す
                                 aget "/1" do
     ランダムな秒数待つ                     waitsec = rand * 2
     “1” や “2” を返す                 EM.add_timer waitsec do
                                     body {"1"}
                                   end
                                 end
                                 aget "/2" do
                                   waitsec = rand * 2
                                   EM.add_timer waitsec do
                                     body {"2"}
                                   end
                                 end
                               end
Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
EventMachine 標準のHTTPClient                             9
                         require 'rubygems'
ライブラリが数多くの               require 'eventmachine'
機能を提供                    require 'uri'

  イベントループ                urls = %W[http://localhost:3000/1
                                   http://localhost:3000/2]
  HTTPプロトコル              pending = urls.length
  コールバック呼出し処理            EventMachine.run do
                           Client = EM::Protocols::HttpClient
client.callback :          urls.each do |url|
  正常取得時の処理を登録                uri = URI(url)
                             client = Client.request(
EM.stop_event_loop             :host => uri.host,
                               :port => uri.port,
  イベントループを終了                   :request => uri.path,
EM標準の HTTPClient             )

はちょっと貧弱                     client.callback do |response|
                              content = response[:content]
   リダイレクトに非対応                 puts "#{url} content"
   プロキシや basic認証に             pending -= 1
   も非対応                       EM.stop_event_loop if pending == 0
                            end
                          end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
                        end
em-http-request                             10
EventMachine 用の          require 'rubygems'
                         require 'eventmachine'
非同期HTTPライブラリ             require 'em-http-request'
高機能                      urls = %W[http://localhost:3000/1
  リダイレクトに追従                        http://localhost:3000/2]
                         pending = urls.length
  Basic 認証に対応            EventMachine.run do
  プロキシ、Sock5に対応            Request = EM::HttpRequest
                           urls.each do |url|
  他にもいろいろ                    client = Request.new(url).get
使い方はほぼ同じ                     client.callback do
  コールバックに終了後の                  response = client.response
  処理を登録                        puts "#{url} #{response}"
                               pending -= 1
                               EM.stop_event_loop if pending == 0
                             end
                           end
                         end



Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
Fiber とは                               11
Fiber とは                                 f1 = Fiber.new do |i|
                                           puts i #=> 1
  軽量スレッド(coroutine)                        Fiber.yield 2
  明示的にスレッドに移ったり、                           5
  スレッドから戻ったり                             end

Fiber.yield arg                          f2 = Fiber.new do |i|
                                           puts 3 #=> 3
  現在のファイバーの処理を中断                           j = Fiber.yield 4
  親ファイバーにもどる                               puts j #=> 6
                                           7
  Fiber#resume の引数が                      end
  Fiber.yield の返り値
                               (表示)      i = f1.resume 1
Fiber#resume arg               1         puts i #=> 2
  そのファイバー(self) の              2         j = f2.resume i + 1
                               3         puts j #=> 4
  中断していた場所から再開                 4         i = f1.resume
  Fiber.yield の引数が             5         puts i #=> 5
  Fiber#resume の返り値            6         j = f2.resume 6
                               7         puts j #=> 7


Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
em-http-request の Fiber による逐次的記述                               12
httpget メソッド内                require
                             require
                                       'rubygems'
                                       'eventmachine'
で、Fiber を利用                  require
                             require
                                       'em-http-request'
                                       'fiber'
EM.run の中は上から順に              urls = %W[http://localhost:3000/1
処理を記述                                  http://localhost:3000/2]
                             def httpget url
  コールバックがない!                   f = Fiber.current
                               client = EM::HttpRequest.new(url).get
  逐次的に記述できている!                 client.callback do
いくつか問題が・・・
                                 f.resume client
                               end
                               return Fiber.yield
  並列処理が行われない                 end
     1個 取得してから               pending = urls.size
     次の処理を実施する               EM.run do
                               Fiber.new do
  自分で Fiber の処理を記述               urls.each do |url|
                                   client = httpget url
     汎用的処理なので、                     puts "#{url} #{client.response}"
     ライブラリに切り出したい
                                   pending -= 1
                                   EM.stop_event_loop if pending == 0
                                 end
                               end.resume
                             end
Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
em-synchrony (1)                                 13
em-synchrony を使うと            require
                             require
                                       'rubygems'
                                       'eventmachine'
  EM.synchrony メソッドを         require   'em-http-request'
                             require   'em-synchrony'
  利用可能になる                    require   'em-synchrony/em-http'
  get メソッドが内部的に
                             urls = %W[http://localhost:3000/1
  Fiber を用いるメソッドに                      http://localhost:3000/2]
  置き換わる
                             EM.synchrony do
  同期的な記述でノンブロッキ                urls.each do |url|
  ング処理を実現できる                     request = EM::HttpRequest.new(url)
                                 res = request.get.response
けど、まだ同時並行処理                      puts "#{url} #{res}"
                               end
は行われない                         EM.stop_event_loop
                             end
  1個ずつURLを取得する
  (涙)




Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
em-synchrony (2)                                 14
複数の URL からの取得を               require
                             require
                                       'rubygems'
                                       'eventmachine'
同時並行で行うには                    require   'em-http-request'
                             require   'em-synchrony'
  それぞれの URL からの取得            require   'em-synchrony/em-http'
  処理を Fiber で囲む
                             urls = %W[http://localhost:3000/1
  それぞれの取得処理が同時に                        http://localhost:3000/2]
  実行される                      pending = urls.length
求めるものが得られた!                  EM.synchrony do
                               urls.each do |url|
  できれば、1000個の URL を              Fiber.new do
                                   request = EM::HttpRequest.new(url)
  5個づつ並行に処理したり                     response = request.get.response
  したいんだけど・・・                       puts "#{url} #{response}"

                                   pending -= 1
                                   EM.stop_event_loop if pending == 0
                                 end.resume
                               end
                             end




Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
EM::Iterator のコールバックによる記述                                  15
EM::Iterator               require 'rubygems'
                           require 'eventmachine'
  EventMachine 用の          require 'em-http-request'
  イテレータ
                           urls = %W[http://localhost:3000/1
  each、map、inject                    http://localhost:3000/2]
  iter.next で
  後続の要素を処理                 concurrency = 2
                           pending = urls.length
  iter.return で            EventMachine.run do
  値を返す                       EM::Iterator.new(urls, concurrency).each
                           do |url, iter|
  new の第2引数で                   client = EM::HTTPRequest.new(url).get
  同時実行数を指定可能                   client.callback do
                                 response = client.response
                                 puts "#{url} #{response}"
                                 pending -= 1
                                 EM.stop_event_loop if pending == 0
                                 iter.next
                               end
                             end
                           end

Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
EM::Synchrony::Iterator                              16
EM::Synchrony::Iterator       require
                              require
                                        'rubygems'
                                        'eventmachine'
   Fiber を使って、each 以降         require   'em-http-request'
                              require   'em-synchrony'
   の処理を、すべての要素の               require   'em-synchrony/em-http'
   処理終了後に実行するもの
                              urls = %W[http://localhost:3000/1
   Fiber で囲むのを                          http://localhost:3000/2]
   なくせると思っていたら
                              concurrency = 2
   そういうものではなかった。              EventMachine.synchrony do
   残りの処理数を管理する                  EM::Synchrony::Iterator.new(urls,
                              concurrency).each do |url, iter|
   変数 pending が不要                 Fiber.new do
                                    client = EM::HttpRequest.new(url)
                                    response = client.get.response
                                    puts "#{url} #{response}"
                                    iter.next
                                  end.resume
                                end
                                EM.stop_event_loop
                              end




Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
落穂拾い(1) em-synchrony の他の機能               17
  複数の主要プロトコルへの対応
     redis、mysql、mongodb、memcached
     自分で新たなプロトコルに対応するのも容易
  EM::Synchrony::Multi
     すべての要素が終了したときに処理を実行するときに使う
  EM::Synchrony::ConnectionPool
     MySQL などのコネクションプーリングで利用可能
   EM::Synchrony::TCPSocket
     TCPSocket クラスをその気になれば代替できるクラス
     setsockopt などいくつかのメソッドが非互換
  EM::Synchrony::Thread::ConditionVariable
     リソースの取得待ちなどが簡単に実現可能



Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
落ち穂拾い(2) いろいろ困ったこと                        18
  Ruby 1.9 が利用可能な環境の構築
     Cygwin ではコンパイルできない
     VMWare で一度チャレンジして途中で挫折
        理由わすれた
     VirtualBox で再度トライしてうまくいった
        VitualBox は VMWare よりずっと使いやすくて便利!
        Windows プログラムの利用がなければ Cygwin よりいいかも。
  em-http-request のインストール
     「gem install --pre em-http-request」とすることが必要
     --pre をつけると、1.0.0.beta4 がインストールされる
        つけないと、0.3.0 がインストールされる
     em-http-request 1.0 系列でないと em-synchrony が使えない
     em-http-request は 0.3 と 1.0 で非互換な部分が多い



Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
まとめ                  19
  スレッドと IO 多重化の2方式で同時並行処理を比較
     (Ruby の場合は)たいていスレッドで十分
     スレッド特有のバグ、速度が遅すぎるなどの課題があれば、
     IO多重化(event machine など)の利用を検討
  Event Machine
     ノンブロッキングIO を実現するライブラリ
     単一イベントループとコールバックによる対応処理の記述
  em-synchrony
     逐次的記述でノンブロッキングな処理が実現可能
     内部実装に、Fiber を利用
     複数の URL からの同時取得処理もかんたん
     コネクションプール




Ruby/Rails勉強会@関西 第50回   「em-synchrony について」
20




ご清聴ありがとう
 ございました

Weitere ähnliche Inhalte

Was ist angesagt?

イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)Yoshitaka Kawashima
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
ダブル配列の実装方法
ダブル配列の実装方法ダブル配列の実装方法
ダブル配列の実装方法Higashiyama Masahiko
 
Quick Search algorithm and strstr
Quick Search algorithm and strstrQuick Search algorithm and strstr
Quick Search algorithm and strstrMITSUNARI Shigeo
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjugYahoo!デベロッパーネットワーク
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)Hiro H.
 
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみたADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみたNarami Kiyokura
 
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 Yugo Shimizu
 
よくわかるHopscotch hashing
よくわかるHopscotch hashingよくわかるHopscotch hashing
よくわかるHopscotch hashingKumazaki Hiroki
 
データベース設計徹底指南
データベース設計徹底指南データベース設計徹底指南
データベース設計徹底指南Mikiya Okuno
 
Apache Arrow - データ処理ツールの次世代プラットフォーム
Apache Arrow - データ処理ツールの次世代プラットフォームApache Arrow - データ処理ツールの次世代プラットフォーム
Apache Arrow - データ処理ツールの次世代プラットフォームKouhei Sutou
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門Tadahiro Ishisaka
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyYasuharu Nakano
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードShigenori Sagawa
 
Developing an Akka Edge6
Developing an Akka Edge6Developing an Akka Edge6
Developing an Akka Edge6saaaaaaki
 

Was ist angesagt? (20)

イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
ダブル配列の実装方法
ダブル配列の実装方法ダブル配列の実装方法
ダブル配列の実装方法
 
Quick Search algorithm and strstr
Quick Search algorithm and strstrQuick Search algorithm and strstr
Quick Search algorithm and strstr
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
 
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみたADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
 
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
 
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajpAt least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
 
よくわかるHopscotch hashing
よくわかるHopscotch hashingよくわかるHopscotch hashing
よくわかるHopscotch hashing
 
データベース設計徹底指南
データベース設計徹底指南データベース設計徹底指南
データベース設計徹底指南
 
MapReduce入門
MapReduce入門MapReduce入門
MapReduce入門
 
プログラムを高速化する話
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話
 
Apache Arrow - データ処理ツールの次世代プラットフォーム
Apache Arrow - データ処理ツールの次世代プラットフォームApache Arrow - データ処理ツールの次世代プラットフォーム
Apache Arrow - データ処理ツールの次世代プラットフォーム
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovy
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
 
Developing an Akka Edge6
Developing an Akka Edge6Developing an Akka Edge6
Developing an Akka Edge6
 

Andere mochten auch

マジックビーンズ
マジックビーンズマジックビーンズ
マジックビーンズAkira Suenami
 
How to measure UIView position on Native App
How to measure UIView position on Native AppHow to measure UIView position on Native App
How to measure UIView position on Native AppDaisuke Yamashita
 
Isucon makers casual talks
Isucon makers casual talksIsucon makers casual talks
Isucon makers casual talksMasahiro Nagano
 
Perl 非同期プログラミング
Perl 非同期プログラミングPerl 非同期プログラミング
Perl 非同期プログラミングlestrrat
 
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -Yuki Anzai
 
kintoneフロントエンド開発 モダン化への道
kintoneフロントエンド開発 モダン化への道kintoneフロントエンド開発 モダン化への道
kintoneフロントエンド開発 モダン化への道Yusuke Amano
 
絶対落ちないアプリの作り方
絶対落ちないアプリの作り方絶対落ちないアプリの作り方
絶対落ちないアプリの作り方Fumihiko Shiroyama
 

Andere mochten auch (9)

Ruby in kansai
Ruby in kansaiRuby in kansai
Ruby in kansai
 
ゲンバのSwift
ゲンバのSwiftゲンバのSwift
ゲンバのSwift
 
マジックビーンズ
マジックビーンズマジックビーンズ
マジックビーンズ
 
How to measure UIView position on Native App
How to measure UIView position on Native AppHow to measure UIView position on Native App
How to measure UIView position on Native App
 
Isucon makers casual talks
Isucon makers casual talksIsucon makers casual talks
Isucon makers casual talks
 
Perl 非同期プログラミング
Perl 非同期プログラミングPerl 非同期プログラミング
Perl 非同期プログラミング
 
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
 
kintoneフロントエンド開発 モダン化への道
kintoneフロントエンド開発 モダン化への道kintoneフロントエンド開発 モダン化への道
kintoneフロントエンド開発 モダン化への道
 
絶対落ちないアプリの作り方
絶対落ちないアプリの作り方絶対落ちないアプリの作り方
絶対落ちないアプリの作り方
 

Ähnlich wie Em synchrony について

.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE).NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)Tusyoshi Matsuzaki
 
18166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi200918166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi2009Muhammad Ali
 
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) 泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) Akihiro Kuwano
 
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolateskoichik
 
20121217 jawsug-yokohama
20121217 jawsug-yokohama20121217 jawsug-yokohama
20121217 jawsug-yokohamaTetsuya Chiba
 
Html5, Web Applications 2
Html5, Web Applications 2Html5, Web Applications 2
Html5, Web Applications 2totty jp
 
Bossan dentoo
Bossan dentooBossan dentoo
Bossan dentookubo39
 
イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化Gosuke Miyashita
 
Tiny server
Tiny serverTiny server
Tiny serverkomem3
 
SlackのIncomingWebhooksとOutgoingWebhooksを使って電子工作と連携させてみよう
SlackのIncomingWebhooksとOutgoingWebhooksを使って電子工作と連携させてみようSlackのIncomingWebhooksとOutgoingWebhooksを使って電子工作と連携させてみよう
SlackのIncomingWebhooksとOutgoingWebhooksを使って電子工作と連携させてみようShigeo Ueda
 
RoRとAWSで100,000Req/Minを処理する
RoRとAWSで100,000Req/Minを処理するRoRとAWSで100,000Req/Minを処理する
RoRとAWSで100,000Req/Minを処理するaktsk
 
Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Yu Nobuoka
 
たのしいNode.js
たのしいNode.jsたのしいNode.js
たのしいNode.jsishiki-takai
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目龍一 田中
 
20101018 JJUG CCC10 WindowsAzure
20101018 JJUG CCC10 WindowsAzure20101018 JJUG CCC10 WindowsAzure
20101018 JJUG CCC10 WindowsAzureShinichiro Isago
 
Echo server implementation for Python
Echo server implementation for PythonEcho server implementation for Python
Echo server implementation for PythonToshiki Tsuboi
 
Kyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseKyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseMikio Hirabayashi
 
Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用kazuyas
 

Ähnlich wie Em synchrony について (20)

.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE).NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
 
Tottoruby 20110903
Tottoruby 20110903Tottoruby 20110903
Tottoruby 20110903
 
18166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi200918166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi2009
 
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) 泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
 
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates
 
20121217 jawsug-yokohama
20121217 jawsug-yokohama20121217 jawsug-yokohama
20121217 jawsug-yokohama
 
Node.js入門
Node.js入門Node.js入門
Node.js入門
 
Html5, Web Applications 2
Html5, Web Applications 2Html5, Web Applications 2
Html5, Web Applications 2
 
Bossan dentoo
Bossan dentooBossan dentoo
Bossan dentoo
 
イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化
 
Tiny server
Tiny serverTiny server
Tiny server
 
SlackのIncomingWebhooksとOutgoingWebhooksを使って電子工作と連携させてみよう
SlackのIncomingWebhooksとOutgoingWebhooksを使って電子工作と連携させてみようSlackのIncomingWebhooksとOutgoingWebhooksを使って電子工作と連携させてみよう
SlackのIncomingWebhooksとOutgoingWebhooksを使って電子工作と連携させてみよう
 
RoRとAWSで100,000Req/Minを処理する
RoRとAWSで100,000Req/Minを処理するRoRとAWSで100,000Req/Minを処理する
RoRとAWSで100,000Req/Minを処理する
 
Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成
 
たのしいNode.js
たのしいNode.jsたのしいNode.js
たのしいNode.js
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目
 
20101018 JJUG CCC10 WindowsAzure
20101018 JJUG CCC10 WindowsAzure20101018 JJUG CCC10 WindowsAzure
20101018 JJUG CCC10 WindowsAzure
 
Echo server implementation for Python
Echo server implementation for PythonEcho server implementation for Python
Echo server implementation for Python
 
Kyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseKyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in Japanese
 
Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用
 

Mehr von Tomoya Kawanishi

ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例Tomoya Kawanishi
 
エンジニア転職のノウハウ
エンジニア転職のノウハウエンジニア転職のノウハウ
エンジニア転職のノウハウTomoya Kawanishi
 
Ruby の文字列について
Ruby の文字列についてRuby の文字列について
Ruby の文字列についてTomoya Kawanishi
 
Ruby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてRuby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてTomoya Kawanishi
 
Ruby初心者からよく質問されること
Ruby初心者からよく質問されることRuby初心者からよく質問されること
Ruby初心者からよく質問されることTomoya Kawanishi
 
RubyGems と Bundler について
RubyGems と Bundler についてRubyGems と Bundler について
RubyGems と Bundler についてTomoya Kawanishi
 
Ruby の正規表現について
Ruby の正規表現についてRuby の正規表現について
Ruby の正規表現についてTomoya Kawanishi
 
Ruby での外部コマンドの実行について
Ruby での外部コマンドの実行についてRuby での外部コマンドの実行について
Ruby での外部コマンドの実行についてTomoya Kawanishi
 
Ruby のワンライナーについて
Ruby のワンライナーについてRuby のワンライナーについて
Ruby のワンライナーについてTomoya Kawanishi
 
AWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことAWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことTomoya Kawanishi
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選Tomoya Kawanishi
 
HTTPと Webクローリングについて
HTTPと WebクローリングについてHTTPと Webクローリングについて
HTTPと WebクローリングについてTomoya Kawanishi
 
Active record query interface
Active record query interfaceActive record query interface
Active record query interfaceTomoya Kawanishi
 
Active Support のコア拡張機能について
Active Support のコア拡張機能についてActive Support のコア拡張機能について
Active Support のコア拡張機能についてTomoya Kawanishi
 
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーRuby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーTomoya Kawanishi
 
RubyのDir、File、IO について
RubyのDir、File、IO についてRubyのDir、File、IO について
RubyのDir、File、IO についてTomoya Kawanishi
 
Thread の利用事例紹介
Thread の利用事例紹介Thread の利用事例紹介
Thread の利用事例紹介Tomoya Kawanishi
 
Ruby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてRuby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてTomoya Kawanishi
 

Mehr von Tomoya Kawanishi (20)

英単語の覚え方
英単語の覚え方英単語の覚え方
英単語の覚え方
 
ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例
 
エンジニア転職のノウハウ
エンジニア転職のノウハウエンジニア転職のノウハウ
エンジニア転職のノウハウ
 
Ruby の文字列について
Ruby の文字列についてRuby の文字列について
Ruby の文字列について
 
Ruby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてRuby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構について
 
Ruby初心者からよく質問されること
Ruby初心者からよく質問されることRuby初心者からよく質問されること
Ruby初心者からよく質問されること
 
RubyGems と Bundler について
RubyGems と Bundler についてRubyGems と Bundler について
RubyGems と Bundler について
 
Ruby の正規表現について
Ruby の正規表現についてRuby の正規表現について
Ruby の正規表現について
 
Ruby での外部コマンドの実行について
Ruby での外部コマンドの実行についてRuby での外部コマンドの実行について
Ruby での外部コマンドの実行について
 
Ruby のワンライナーについて
Ruby のワンライナーについてRuby のワンライナーについて
Ruby のワンライナーについて
 
AWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことAWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったこと
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
 
HTTPと Webクローリングについて
HTTPと WebクローリングについてHTTPと Webクローリングについて
HTTPと Webクローリングについて
 
Rake
RakeRake
Rake
 
Active record query interface
Active record query interfaceActive record query interface
Active record query interface
 
Active Support のコア拡張機能について
Active Support のコア拡張機能についてActive Support のコア拡張機能について
Active Support のコア拡張機能について
 
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーRuby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
 
RubyのDir、File、IO について
RubyのDir、File、IO についてRubyのDir、File、IO について
RubyのDir、File、IO について
 
Thread の利用事例紹介
Thread の利用事例紹介Thread の利用事例紹介
Thread の利用事例紹介
 
Ruby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてRuby の制御構造とリテラルについて
Ruby の制御構造とリテラルについて
 

Kürzlich hochgeladen

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 

Kürzlich hochgeladen (7)

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 

Em synchrony について

  • 1. em-synchrony について 2011年8月6日 cuzic
  • 2. 自己紹介 1 cuzic といいます きゅーじっく と読みます Ruby 暦は かれこれもう10年くらい 近況 Nook Simple Touch というデバイスを買いました Android 2.1 が動く、ディスプレイが e-ink の端末 定期巡回している Web 記事を快適に読めてしあわせ 今後の勉強会予定 8月20日(土) Coders At Work 読書会 #2 今回と同じ会場です 2週間後! みんな来てください。 Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 3. 今日の議題 2 • 複数処理の同時並行実行について • マルチスレッドによる同時並行処理 従来の • IO多重化 による同時並行処理 並列処理 • eventmachine とは event- • コールバック登録による非同期処理 machine • Fiber とは em- • 非同期処理の逐次処理的な記述 synchrony Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 4. 同時並行で処理を進めて高速化したい! 3 過剰な待ち時間のために、動作が遅かったりします 例) WEBダウンロード ネットワークIO の待ち時間の間は CPU は働きません CPU としては軽い処理なのに、もったいない! ⇒ 多数の URL からのダウンロードであれば、同時並行で ダウンロードさせれば、高速化可能。 同時に処理させる方法の例 マルチスレッド スレッド特有の問題が多数存在 (排他制御、デッドロック、変数の同期 etc) IO 多重化(select(2) の利用など) 状態の管理が大変。慣れるまでは苦労する。 マルチプロセス 今回は説明しません Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 5. マルチスレッドによる同時並行処理 4 マルチスレッドの長所 require 'open-uri' 書きやすい urls = %W[http://localhost:3000/1 同期処理的に書ける http://localhost:3000/2 ] urls.each do |url| (Ruby の場合は) puts "#{url} #{open(url).read}" 自動的にIO 多重化を end いいかんじにできる (Ruby の場合)たいてい、 マルチスレッドで十分! require 'open-uri' マルチスレッドの短所 urls = %W[http://localhost:3000/1 スレッド特有の多々の問題 http://localhost:3000/2] 排他制御 threads = urls.map do |url| Thread.start(url) do |url| デッドロック body = open(url).read たまに起きる不可解なバグ puts "#{uri} #{body}" スレッド切り替えが遅い end end コンテキスト切替が必要 いつ何が動作している不明 threads.each{|t| t.join} Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 6. IO多重化 による同時並行処理 5 IO多重化の長所 AsyncHTTPClient の作成 動きがすばやい 巡回したい URL と、 読み込み後にしたい処理 スレッド特有の各種問題に (コールバック)を登録 悩まされない HTTP 取得処理を実行 IO多重化の短所 取得終了後、登録していた 慣れるまで書きにくい コールバックを呼び出し 逐次的に処理を書けない 慣れが必要 sockets = ソケット作成処理(urls) 状態遷移を管理したり、 loop do コールバックの登録が readables, = IO.select sockets 常套手段 readables.each do |s| select(2) を使うプログラム バッファ = s.read_nonblock 65536 sockets.delete s if s.eof? を書くのは結構大変 end ⇒ そういうときには end eventmachine break if sockets.empty? end 登録していたコールバック呼び出し Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 7. これからの説明 6 eventmachine em-http-request eventmachine 標準の HTTP による とは クライアント HTTPクライアント Fiber を使った em-synchrony Fiber とは 非同期処理の を使った 逐次的記述 逐次的記述 EM::Iterator の EM::Synchrony:: コールバックによ Iteratorによる その他 落穂拾い る記述 逐次的記述 Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 8. eventmachine とは 7 非常に有名なノンブロッキングIO を実現するライブラリ Heroku 、 Github、 EngineYard などで利用されている 広範なプロトコルに対応 HTTP、SMTP、MySQL 、PostgreSQL、Memcached、Redis 内部的には select(2) による IO 多重化を実現 環境次第では、epoll 、kqueue なども利用可能 非常にスケーラブルな IO 多重化が可能 読み込み処理終了などの”イベント”に対応した処理を記述 返り値は使わず、コールバックを登録する コールバックの中は、処理完了後に実行される ret1 = 処理1(引数) 処理1(引数) do |ret| ret2 = 処理2(ret1) 処理2(ret1) do |ret2| その後の処理 その後の処理 end end Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 9. サーバーサイドのスクリプト 8 sinatra/async require 'rubygems' require 'sinatra' WEBフレームワーク require 'sinatra/base' Sinatra の非同期 版 require 'sinatra/async' require 'eventmachine' aget が get の非同期 版 仕様 class Delayed < Sinatra::Base register Sinatra::Async /1 と /2 に応答を返す aget "/1" do ランダムな秒数待つ waitsec = rand * 2 “1” や “2” を返す EM.add_timer waitsec do body {"1"} end end aget "/2" do waitsec = rand * 2 EM.add_timer waitsec do body {"2"} end end end Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 10. EventMachine 標準のHTTPClient 9 require 'rubygems' ライブラリが数多くの require 'eventmachine' 機能を提供 require 'uri' イベントループ urls = %W[http://localhost:3000/1 http://localhost:3000/2] HTTPプロトコル pending = urls.length コールバック呼出し処理 EventMachine.run do Client = EM::Protocols::HttpClient client.callback : urls.each do |url| 正常取得時の処理を登録 uri = URI(url) client = Client.request( EM.stop_event_loop :host => uri.host, :port => uri.port, イベントループを終了 :request => uri.path, EM標準の HTTPClient ) はちょっと貧弱 client.callback do |response| content = response[:content] リダイレクトに非対応 puts "#{url} content" プロキシや basic認証に pending -= 1 も非対応 EM.stop_event_loop if pending == 0 end end Ruby/Rails勉強会@関西 第50回 「em-synchrony について」 end
  • 11. em-http-request 10 EventMachine 用の require 'rubygems' require 'eventmachine' 非同期HTTPライブラリ require 'em-http-request' 高機能 urls = %W[http://localhost:3000/1 リダイレクトに追従 http://localhost:3000/2] pending = urls.length Basic 認証に対応 EventMachine.run do プロキシ、Sock5に対応 Request = EM::HttpRequest urls.each do |url| 他にもいろいろ client = Request.new(url).get 使い方はほぼ同じ client.callback do コールバックに終了後の response = client.response 処理を登録 puts "#{url} #{response}" pending -= 1 EM.stop_event_loop if pending == 0 end end end Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 12. Fiber とは 11 Fiber とは f1 = Fiber.new do |i| puts i #=> 1 軽量スレッド(coroutine) Fiber.yield 2 明示的にスレッドに移ったり、 5 スレッドから戻ったり end Fiber.yield arg f2 = Fiber.new do |i| puts 3 #=> 3 現在のファイバーの処理を中断 j = Fiber.yield 4 親ファイバーにもどる puts j #=> 6 7 Fiber#resume の引数が end Fiber.yield の返り値 (表示) i = f1.resume 1 Fiber#resume arg 1 puts i #=> 2 そのファイバー(self) の 2 j = f2.resume i + 1 3 puts j #=> 4 中断していた場所から再開 4 i = f1.resume Fiber.yield の引数が 5 puts i #=> 5 Fiber#resume の返り値 6 j = f2.resume 6 7 puts j #=> 7 Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 13. em-http-request の Fiber による逐次的記述 12 httpget メソッド内 require require 'rubygems' 'eventmachine' で、Fiber を利用 require require 'em-http-request' 'fiber' EM.run の中は上から順に urls = %W[http://localhost:3000/1 処理を記述 http://localhost:3000/2] def httpget url コールバックがない! f = Fiber.current client = EM::HttpRequest.new(url).get 逐次的に記述できている! client.callback do いくつか問題が・・・ f.resume client end return Fiber.yield 並列処理が行われない end 1個 取得してから pending = urls.size 次の処理を実施する EM.run do Fiber.new do 自分で Fiber の処理を記述 urls.each do |url| client = httpget url 汎用的処理なので、 puts "#{url} #{client.response}" ライブラリに切り出したい pending -= 1 EM.stop_event_loop if pending == 0 end end.resume end Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 14. em-synchrony (1) 13 em-synchrony を使うと require require 'rubygems' 'eventmachine' EM.synchrony メソッドを require 'em-http-request' require 'em-synchrony' 利用可能になる require 'em-synchrony/em-http' get メソッドが内部的に urls = %W[http://localhost:3000/1 Fiber を用いるメソッドに http://localhost:3000/2] 置き換わる EM.synchrony do 同期的な記述でノンブロッキ urls.each do |url| ング処理を実現できる request = EM::HttpRequest.new(url) res = request.get.response けど、まだ同時並行処理 puts "#{url} #{res}" end は行われない EM.stop_event_loop end 1個ずつURLを取得する (涙) Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 15. em-synchrony (2) 14 複数の URL からの取得を require require 'rubygems' 'eventmachine' 同時並行で行うには require 'em-http-request' require 'em-synchrony' それぞれの URL からの取得 require 'em-synchrony/em-http' 処理を Fiber で囲む urls = %W[http://localhost:3000/1 それぞれの取得処理が同時に http://localhost:3000/2] 実行される pending = urls.length 求めるものが得られた! EM.synchrony do urls.each do |url| できれば、1000個の URL を Fiber.new do request = EM::HttpRequest.new(url) 5個づつ並行に処理したり response = request.get.response したいんだけど・・・ puts "#{url} #{response}" pending -= 1 EM.stop_event_loop if pending == 0 end.resume end end Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 16. EM::Iterator のコールバックによる記述 15 EM::Iterator require 'rubygems' require 'eventmachine' EventMachine 用の require 'em-http-request' イテレータ urls = %W[http://localhost:3000/1 each、map、inject http://localhost:3000/2] iter.next で 後続の要素を処理 concurrency = 2 pending = urls.length iter.return で EventMachine.run do 値を返す EM::Iterator.new(urls, concurrency).each do |url, iter| new の第2引数で client = EM::HTTPRequest.new(url).get 同時実行数を指定可能 client.callback do response = client.response puts "#{url} #{response}" pending -= 1 EM.stop_event_loop if pending == 0 iter.next end end end Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 17. EM::Synchrony::Iterator 16 EM::Synchrony::Iterator require require 'rubygems' 'eventmachine' Fiber を使って、each 以降 require 'em-http-request' require 'em-synchrony' の処理を、すべての要素の require 'em-synchrony/em-http' 処理終了後に実行するもの urls = %W[http://localhost:3000/1 Fiber で囲むのを http://localhost:3000/2] なくせると思っていたら concurrency = 2 そういうものではなかった。 EventMachine.synchrony do 残りの処理数を管理する EM::Synchrony::Iterator.new(urls, concurrency).each do |url, iter| 変数 pending が不要 Fiber.new do client = EM::HttpRequest.new(url) response = client.get.response puts "#{url} #{response}" iter.next end.resume end EM.stop_event_loop end Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 18. 落穂拾い(1) em-synchrony の他の機能 17 複数の主要プロトコルへの対応 redis、mysql、mongodb、memcached 自分で新たなプロトコルに対応するのも容易 EM::Synchrony::Multi すべての要素が終了したときに処理を実行するときに使う EM::Synchrony::ConnectionPool MySQL などのコネクションプーリングで利用可能 EM::Synchrony::TCPSocket TCPSocket クラスをその気になれば代替できるクラス setsockopt などいくつかのメソッドが非互換 EM::Synchrony::Thread::ConditionVariable リソースの取得待ちなどが簡単に実現可能 Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 19. 落ち穂拾い(2) いろいろ困ったこと 18 Ruby 1.9 が利用可能な環境の構築 Cygwin ではコンパイルできない VMWare で一度チャレンジして途中で挫折 理由わすれた VirtualBox で再度トライしてうまくいった VitualBox は VMWare よりずっと使いやすくて便利! Windows プログラムの利用がなければ Cygwin よりいいかも。 em-http-request のインストール 「gem install --pre em-http-request」とすることが必要 --pre をつけると、1.0.0.beta4 がインストールされる つけないと、0.3.0 がインストールされる em-http-request 1.0 系列でないと em-synchrony が使えない em-http-request は 0.3 と 1.0 で非互換な部分が多い Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
  • 20. まとめ 19 スレッドと IO 多重化の2方式で同時並行処理を比較 (Ruby の場合は)たいていスレッドで十分 スレッド特有のバグ、速度が遅すぎるなどの課題があれば、 IO多重化(event machine など)の利用を検討 Event Machine ノンブロッキングIO を実現するライブラリ 単一イベントループとコールバックによる対応処理の記述 em-synchrony 逐次的記述でノンブロッキングな処理が実現可能 内部実装に、Fiber を利用 複数の URL からの同時取得処理もかんたん コネクションプール Ruby/Rails勉強会@関西 第50回 「em-synchrony について」