SlideShare a Scribd company logo
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

OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
Daichi Koike
 
ioMemoryとAtomic Writeによるデータベース高速化
ioMemoryとAtomic Writeによるデータベース高速化ioMemoryとAtomic Writeによるデータベース高速化
ioMemoryとAtomic Writeによるデータベース高速化
IIJ
 
웹서버 부하테스트 실전 노하우
웹서버 부하테스트 실전 노하우웹서버 부하테스트 실전 노하우
웹서버 부하테스트 실전 노하우
IMQA
 
與大師對談: 轉移到微服務架構必經之路 ~ 系統與資料庫重構
與大師對談: 轉移到微服務架構必經之路~ 系統與資料庫重構與大師對談: 轉移到微服務架構必經之路~ 系統與資料庫重構
與大師對談: 轉移到微服務架構必經之路 ~ 系統與資料庫重構
Andrew Wu
 
Automated Malware Analysis and Cyber Security Intelligence
Automated Malware Analysis and Cyber Security IntelligenceAutomated Malware Analysis and Cyber Security Intelligence
Automated Malware Analysis and Cyber Security Intelligence
Jason Choi
 
NginxとLuaを用いた動的なリバースプロキシでデプロイを 100 倍速くした
NginxとLuaを用いた動的なリバースプロキシでデプロイを 100 倍速くしたNginxとLuaを用いた動的なリバースプロキシでデプロイを 100 倍速くした
NginxとLuaを用いた動的なリバースプロキシでデプロイを 100 倍速くした
toshi_pp
 
NoSql Injection
NoSql InjectionNoSql Injection
NoSql Injection
NSConclave
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
murachue
 
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
モノビット エンジン
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
yoku0825
 
これから始める人のための自動化入門~Ubuntu Jujuを使って〜– OpenStack最新情報セミナー 2015年7月
これから始める人のための自動化入門~Ubuntu Jujuを使って〜– OpenStack最新情報セミナー 2015年7月これから始める人のための自動化入門~Ubuntu Jujuを使って〜– OpenStack最新情報セミナー 2015年7月
これから始める人のための自動化入門~Ubuntu Jujuを使って〜– OpenStack最新情報セミナー 2015年7月
VirtualTech Japan Inc.
 
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Hiro H.
 
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術Masahiro Nagano
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
kwatch
 
Building Active Directory Monitoring with Telegraf, InfluxDB, and Grafana
Building Active Directory Monitoring with Telegraf, InfluxDB, and GrafanaBuilding Active Directory Monitoring with Telegraf, InfluxDB, and Grafana
Building Active Directory Monitoring with Telegraf, InfluxDB, and Grafana
Boni Yeamin
 
01 Metasploit kung fu introduction
01 Metasploit kung fu introduction01 Metasploit kung fu introduction
01 Metasploit kung fu introduction
Mostafa Abdel-sallam
 
MySQLレプリケーションあれやこれや
MySQLレプリケーションあれやこれやMySQLレプリケーションあれやこれや
MySQLレプリケーションあれやこれや
yoku0825
 
Evolveum: midPoint Deployment Example
Evolveum: midPoint Deployment ExampleEvolveum: midPoint Deployment Example
Evolveum: midPoint Deployment Example
Evolveum
 
IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교
JungWoon Lee
 
そのRails Engine、 本当に必要ですか?
そのRails Engine、 本当に必要ですか?そのRails Engine、 本当に必要ですか?
そのRails Engine、 本当に必要ですか?
nixiesan
 

What's hot (20)

OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
 
ioMemoryとAtomic Writeによるデータベース高速化
ioMemoryとAtomic Writeによるデータベース高速化ioMemoryとAtomic Writeによるデータベース高速化
ioMemoryとAtomic Writeによるデータベース高速化
 
웹서버 부하테스트 실전 노하우
웹서버 부하테스트 실전 노하우웹서버 부하테스트 실전 노하우
웹서버 부하테스트 실전 노하우
 
與大師對談: 轉移到微服務架構必經之路 ~ 系統與資料庫重構
與大師對談: 轉移到微服務架構必經之路~ 系統與資料庫重構與大師對談: 轉移到微服務架構必經之路~ 系統與資料庫重構
與大師對談: 轉移到微服務架構必經之路 ~ 系統與資料庫重構
 
Automated Malware Analysis and Cyber Security Intelligence
Automated Malware Analysis and Cyber Security IntelligenceAutomated Malware Analysis and Cyber Security Intelligence
Automated Malware Analysis and Cyber Security Intelligence
 
NginxとLuaを用いた動的なリバースプロキシでデプロイを 100 倍速くした
NginxとLuaを用いた動的なリバースプロキシでデプロイを 100 倍速くしたNginxとLuaを用いた動的なリバースプロキシでデプロイを 100 倍速くした
NginxとLuaを用いた動的なリバースプロキシでデプロイを 100 倍速くした
 
NoSql Injection
NoSql InjectionNoSql Injection
NoSql Injection
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
これから始める人のための自動化入門~Ubuntu Jujuを使って〜– OpenStack最新情報セミナー 2015年7月
これから始める人のための自動化入門~Ubuntu Jujuを使って〜– OpenStack最新情報セミナー 2015年7月これから始める人のための自動化入門~Ubuntu Jujuを使って〜– OpenStack最新情報セミナー 2015年7月
これから始める人のための自動化入門~Ubuntu Jujuを使って〜– OpenStack最新情報セミナー 2015年7月
 
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
 
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
Building Active Directory Monitoring with Telegraf, InfluxDB, and Grafana
Building Active Directory Monitoring with Telegraf, InfluxDB, and GrafanaBuilding Active Directory Monitoring with Telegraf, InfluxDB, and Grafana
Building Active Directory Monitoring with Telegraf, InfluxDB, and Grafana
 
01 Metasploit kung fu introduction
01 Metasploit kung fu introduction01 Metasploit kung fu introduction
01 Metasploit kung fu introduction
 
MySQLレプリケーションあれやこれや
MySQLレプリケーションあれやこれやMySQLレプリケーションあれやこれや
MySQLレプリケーションあれやこれや
 
Evolveum: midPoint Deployment Example
Evolveum: midPoint Deployment ExampleEvolveum: midPoint Deployment Example
Evolveum: midPoint Deployment Example
 
IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교
 
そのRails Engine、 本当に必要ですか?
そのRails Engine、 本当に必要ですか?そのRails Engine、 本当に必要ですか?
そのRails Engine、 本当に必要ですか?
 

Viewers also liked

Ruby in kansai
Ruby in kansaiRuby in kansai
Ruby in kansai
Tomoya Kawanishi
 
ゲンバのSwift
ゲンバのSwiftゲンバのSwift
ゲンバのSwift
Yuichi Adachi
 
マジックビーンズ
マジックビーンズマジックビーンズ
マジックビーンズ
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 App
Daisuke 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
 
Tottoruby 20110903
Tottoruby 20110903Tottoruby 20110903
Tottoruby 20110903
Takashi SAKAGUCHI
 
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 server
komem3
 
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 WindowsAzure
Shinichiro Isago
 
Echo server implementation for Python
Echo server implementation for PythonEcho server implementation for Python
Echo server implementation for Python
Toshiki 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
 

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
 
Kyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseKyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in Japanese
 
Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用Trema の紹介とネットワーク仮想化への応用
Trema の紹介とネットワーク仮想化への応用
 

More from Tomoya Kawanishi

英単語の覚え方
英単語の覚え方英単語の覚え方
英単語の覚え方
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
 
Rake
RakeRake
Active record query interface
Active record query interfaceActive record query interface
Active record query interface
Tomoya 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

遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
t m
 
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
Toru Tamaki
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
0207sukipio
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
chiefujita1
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
Matsushita Laboratory
 
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援しますキンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
Takayuki Nakayama
 
Generating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language ModelsGenerating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language Models
harmonylab
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 

Recently uploaded (8)

遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
 
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
 
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援しますキンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
 
Generating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language ModelsGenerating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language Models
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 

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