SlideShare a Scribd company logo
1 of 21
Download to read offline
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




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

More Related Content

What's hot

比較サイトの検索改善(SPA から SSR に変換)
比較サイトの検索改善(SPA から SSR に変換)比較サイトの検索改善(SPA から SSR に変換)
比較サイトの検索改善(SPA から SSR に変換)gree_tech
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
トランザクションの並行実行制御 rev.2
トランザクションの並行実行制御 rev.2トランザクションの並行実行制御 rev.2
トランザクションの並行実行制御 rev.2Takashi Hoshino
 
あなたの価値を高めるWebアクセシビリティ
あなたの価値を高めるWebアクセシビリティあなたの価値を高めるWebアクセシビリティ
あなたの価値を高めるWebアクセシビリティ力也 伊原
 
MS Officeファイル暗号化のマスター鍵を利用したバックドアとその対策
MS Officeファイル暗号化のマスター鍵を利用したバックドアとその対策MS Officeファイル暗号化のマスター鍵を利用したバックドアとその対策
MS Officeファイル暗号化のマスター鍵を利用したバックドアとその対策MITSUNARI Shigeo
 
LineairDB: Fast and Embedded Transactional Key-Value Storage
LineairDB: Fast and Embedded Transactional Key-Value StorageLineairDB: Fast and Embedded Transactional Key-Value Storage
LineairDB: Fast and Embedded Transactional Key-Value StorageSho Nakazono
 
Ruby 勉強会 第42回 発表資料 IO について
Ruby 勉強会 第42回 発表資料 IO についてRuby 勉強会 第42回 発表資料 IO について
Ruby 勉強会 第42回 発表資料 IO についてTomoya Kawanishi
 
20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdfKazuaki Ishizaki
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Resultsmametter
 
TiDBのトランザクション
TiDBのトランザクションTiDBのトランザクション
TiDBのトランザクションAkio Mitobe
 
そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?takezoe
 
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11Sadayuki Furuhashi
 
LineairDBの紹介
LineairDBの紹介LineairDBの紹介
LineairDBの紹介Sho Nakazono
 
ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク7shi
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with KarateTakanori Suzuki
 
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方Hiroshi Tokumaru
 
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
 Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術までAkihiro Suda
 
MySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことMySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことyoku0825
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjugYahoo!デベロッパーネットワーク
 

What's hot (20)

比較サイトの検索改善(SPA から SSR に変換)
比較サイトの検索改善(SPA から SSR に変換)比較サイトの検索改善(SPA から SSR に変換)
比較サイトの検索改善(SPA から SSR に変換)
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
トランザクションの並行実行制御 rev.2
トランザクションの並行実行制御 rev.2トランザクションの並行実行制御 rev.2
トランザクションの並行実行制御 rev.2
 
あなたの価値を高めるWebアクセシビリティ
あなたの価値を高めるWebアクセシビリティあなたの価値を高めるWebアクセシビリティ
あなたの価値を高めるWebアクセシビリティ
 
MS Officeファイル暗号化のマスター鍵を利用したバックドアとその対策
MS Officeファイル暗号化のマスター鍵を利用したバックドアとその対策MS Officeファイル暗号化のマスター鍵を利用したバックドアとその対策
MS Officeファイル暗号化のマスター鍵を利用したバックドアとその対策
 
LineairDB: Fast and Embedded Transactional Key-Value Storage
LineairDB: Fast and Embedded Transactional Key-Value StorageLineairDB: Fast and Embedded Transactional Key-Value Storage
LineairDB: Fast and Embedded Transactional Key-Value Storage
 
Ruby 勉強会 第42回 発表資料 IO について
Ruby 勉強会 第42回 発表資料 IO についてRuby 勉強会 第42回 発表資料 IO について
Ruby 勉強会 第42回 発表資料 IO について
 
20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Results
 
TiDBのトランザクション
TiDBのトランザクションTiDBのトランザクション
TiDBのトランザクション
 
そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?
 
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
 
LineairDBの紹介
LineairDBの紹介LineairDBの紹介
LineairDBの紹介
 
ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate
 
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
 
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
 Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
MySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことMySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいこと
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
 

Viewers also liked

マジックビーンズ
マジックビーンズマジックビーンズ
マジックビーンズ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
 

Viewers also liked (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フロントエンド開発 モダン化への道
 
絶対落ちないアプリの作り方
絶対落ちないアプリの作り方絶対落ちないアプリの作り方
絶対落ちないアプリの作り方
 

Similar to 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
 
Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用kazuyas
 
Webサーバのチューニング
WebサーバのチューニングWebサーバのチューニング
WebサーバのチューニングYu Komiya
 

Similar to 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
 
Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用
 
Webサーバのチューニング
WebサーバのチューニングWebサーバのチューニング
Webサーバのチューニング
 

More from 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
 

More from 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 の制御構造とリテラルについて
 

Recently uploaded

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 

Recently uploaded (9)

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 

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 について」