Upgrade to Pro — share decks privately, control downloads, hide ads and more …

避けられないI/O待ちに対処する:
Rails アプリにおけるSSEとasync gemの活用...

Avatar for moznion moznion
September 26, 2025

避けられないI/O待ちに対処する:
Rails アプリにおけるSSEとasync gemの活用 / Tackling Inevitable I/O Latency in Rails Apps with SSE and the async gem

Kaigi on Rails 2025の発表資料です #kaigionrails

Avatar for moznion

moznion

September 26, 2025
Tweet

More Decks by moznion

Other Decks in Technology

Transcript

  1. X

  2.  44&ͱ͸ Ұ౓ΫϥΠΞϯταʔόʔؒͰ )551ͷ44&ίωΫγϣϯΛுΔͱɺ αʔόʔ͔ΒΫϥΠΞϯτʹରͯ͠ ܧଓతʹσʔλΛૹग़Ͱ͖Δ࢓૊Έ ͬ͘͟Γݴ͏ͱ ఻౷తʹ͸ɺ΢Σϒϖʔδ͕৽ͨͳσʔλΛड͚औΔͨΊʹɺ αʔόʔʹϦΫΤετΛૹ৴͠ͳ͚Ε͹ͳΓ·ͤΜɻ͢ͳΘͪɺ ϖʔδ͕αʔόʔ͔ΒσʔλΛཁٻ͠·͢ɻαʔόʔૹ৴Πϕϯ

    τʹΑͬͯɺαʔόʔ͕΢ΣϒϖʔδʹϝοηʔδΛϓογϡૹ ৴͢Δ͜ͱʹΑΓɺαʔόʔ͔Β΢Σϒϖʔδ΁৽ͨͳσʔλΛ ͍ͭͰ΋ૹ৴͢Δ͜ͱ͕Ͱ͖·͢ɻ IUUQTEFWFMPQFSNP[JMMBPSHKBEPDT8FC"1*4FSWFS TFOU@FWFOUT z ௨ৗͷ)551 44&
  3.  ͲͷΑ͏ͳঢ়گͰ44&͸༗ޮ͔ ‣χϡʔεͷΞοϓσʔτ ଎ใ  ‣ϩάͷετϦʔϛϯάදࣔ ‣ϝοηʔδϯάɾνϟοτ ‣,P3ͷαϒεΫϦʔϯ̈  ‣௕͔͔࣌ؒΔॲཧͷʜ

    ‣ਐḿදࣔ ‣׬ྃ௨஌ ྫ ˢ$IBU(15΋44&Ͱಈ࡞͍ͯ͠Δͱ͍͏ྫ ̈IUUQTHJUIVCDPNLBJHJPOSBJMTTIJSBUBLJ
  4.  Ϣʔβʔମݧ޲্ࢪࡦͷҰछ ࡢࠓͷΞϓϦͩͱΑ͋͘Δ ‣"1*31$ݺͼग़͠ ‣"* --. ਪ࿦ ӈਤ͸ϫϯόϯΫΞϓϦͷʮ"*εΫγϣಡΈऔΓػೳʯ ྫ௕͍଴ͪ࣌ؒ FH

    *0XBJU ͕ൃੜ͢Δॲཧͷਐḿ εΫγϣը૾Λ0$3ͯ͠--.͕৘ใநग़͢Δػೳ ͜ͷҰ࿈ͷॲཧΛ44&ʹͯ͠ਐḿΛදࣔ͢Δ
  5.  ΠϕϯτετϦʔϜॲཧ ߦͷछผ͸ҎԼͷ௨Γ ߦ͕ۭന ۭനߦ  ‣σϦϛλͱͯ͠ѻ͍ɺΠϕϯτΛॲཧ͢Δ ߦ͕ίϩϯ͔Β࢝·͍ͬͯΔ ‣ແࢹ͞ΕΔ ϋʔτϏʔτʹศར

     ߦʹίϩϯؚ͕·Ε͍ͯΔ৔߹ ‣ίϩϯʹΑΔ,FZ 'JFME ͱ7BMVFͱͯ͠ ѻ͏ ޙड़  ͦΕҎ֎ ‣ߦશମΛ'JFMEͱۭͯ͠จࣈΛ7BMVFͱ͠ ͯѻ͏
  6.  ΠϕϯτετϦʔϜॲཧ ྫ : test stream data : first event

    id : 1 data : second event id data : third event ίϩϯ͔Β͸͡·Δϝοηʔδ͸ແࢹ͞ΕΔ ͜ͷϒϩοΫͰ͸Կ΋ൃੜ͠ͳ͍
  7.  ΠϕϯτετϦʔϜॲཧ ྫ : test stream data : first event

    id : 1 data : second event id data : third event EBUB͕ fi STUFWFOU JE͕ ͱͯ͠ϒϩοΫ͕ॲཧ͞ΕΔ
  8.  ΠϕϯτετϦʔϜॲཧ ྫ : test stream data : first event

    id : 1 data : second event id data : third event EBUB͕TFDPOEFWFOU JE͕ۭจࣈྻ VOTFU  ͱͯ͠ϒϩοΫ͕ॲཧ͞ΕΔ
  9.  ΠϕϯτετϦʔϜॲཧ ྫ : test stream data : first event

    id : 1 data : second event id data : third event EBUB͕UIJSEFWFOU ͱͯ͠ΠϕϯτϒϩοΫ͕ॲཧ͞ΕΔ ۭߦͰऴ୺͞Ε͍ͯͳ͍ͱΠϕϯτ͕ൃՐ͠ͳ͍
  10.  BTZODHFN 5ISFBE ‣(7-ͷӨڹΛड͚Δ͕ɺ*0଴ͪͳͲ͸ฒྻԽͰ͖Δ ‣ϝϞϦϦιʔεΛ৯͏େྔʹTQBXOͰ͖ͳ͍ 'JCFS ‣ڠௐత ΠϕϯτϧʔϓͱϊϯϒϩοΩϯά*0  ‣ϝϞϦϦιʔεʹର͢Δ༏Ґੑ͕͋Δ

    ‣$16ό΢ϯυͳॲཧ͸ฒྻԽͰ͖ͳ͍ ‣ϒϩοΩϯάॲཧ͕ೖΔͱશମΛϒϩοΫ͢Δ ‣ؔ࿈͢Δίϯϙʔωϯτ͕ඇಉظ*0ɾ'JCFS BXBSFͰ͋Δඞཁ͕͋Δ
  11.  BTZODHFN 5ISFBE ‣(7-ͷӨڹΛड͚Δ͕ɺ*0଴ͪͳͲ͸ฒྻԽͰ͖Δ ‣ϝϞϦϦιʔεΛ৯͏େྔʹTQBXOͰ͖ͳ͍ 'JCFS ‣ڠௐత ΠϕϯτϧʔϓͱϊϯϒϩοΩϯά*0  ‣ϝϞϦϦιʔεʹର͢Δ༏Ґੑ͕͋Δ

    ‣$16ό΢ϯυͳॲཧ͸ฒྻԽͰ͖ͳ͍ ‣ϒϩοΩϯάॲཧ͕ೖΔͱશମΛϒϩοΫ͢Δ ‣ؔ࿈͢Δίϯϙʔωϯτ͕ඇಉظ*0ɾ'JCFS BXBSFͰ͋Δඞཁ͕͋Δ *0଴ͪաଟͳ λΠϓͷΞϓϦ Ͱ͸5ISFBEΑΓ εέʔϧ͢Δ Մೳੑ͕ߴ͍
  12.  "TZODλεΫͷಉ࣮࣌ߦ਺੍ݶ #BSSJFSͱ4FNBQIPSFΛ ૊Έ߹ΘͤΔͱྑ͍ ‣4FNBQIPSFʹ࠷େฒྻ࣮ߦ਺ͱ #BSSJFSΛ༩͑Δ ‣A4FNBQIPSFBTZODAͷதͰ ॲཧ͢Δͱ࣮ߦ਺Λ੍ݶͰ͖Δ ‣A#BSSJFSXBJUAͰ׬ྃ଴ͪ 

    XFMMEPDVNFOUFEͰ࠷ߴ ‣ IUUQTTPDLFUSZHJUIVCJPBTZODHVJEFTUBTLTJOEFYIUNMDPNCJOJOHBCBSSJFSXJUIBTFNBQIPSF ‣ IUUQTTPDLFUSZHJUIVCJPBTZODHVJEFTCFTUQSBDUJDFTJOEFYIUNMVTFBUPQMFWFMTZODUPEFOPUFUIFSPPUPGZPVSQSPHSBN
  13.  "TZODλεΫͷλΠϜΞ΢τઃఆ A5BTLXJUI@UJNFPVUAΛ࢖͏ͱྑ͍ ‣λΠϜΞ΢τ͠͏ΔॲཧΛ ίʔυϒϩοΫͰ༩͑Δ ‣λΠϜΞ΢τͨ͠Β A"TZOD5JNFPVU&SSPSA্͕͕Δ  XFMMEPDVNFOUFEͰ࠷ߴ ‣

    IUUQTTPDLFUSZHJUIVCJPBTZODHVJEFTUBTLTJOEFYIUNMUJNFPVUT ‣ IUUQTTPDLFUSZHJUIVCJPBTZODHVJEFTCFTUQSBDUJDFTJOEFYIUNMVTFBUPQMFWFMTZODUPEFOPUFUIFSPPUPGZPVSQSPHSBN
  14.  44&ͱ૊Έ߹Θ࣮ͤͨ૷ύλʔϯ ΠϨΪϡϥʔ BTZODUBTL಺͔Β"DUJWF3FDPSE NZTRM ͷίωΫγϣϯΛCPSSPX͢Δͱɺ ಈ࡞தͷ5ISFBE಺ͷίωΫγϣϯΛआ༻͢Δ͜ͱʹͳΔɻ आΓ͖ͯͨ ୯Ұ5ISFBEʹׂΓ౰ͯΒΕͨ ίωΫγϣϯΛ'JCFSԣஅͰ

    ࢖͍ճ͢ͱϦιʔεڝ߹͕ൃੜͯ͠Ϋϥογϡͯ͠͠·͏ɻ ্هͷΑ͏ʹεϨουϓʔϧͱίωΫγϣϯϓʔϧΛซ༻͠ɺ TQBXO͞Εͨ5ISFBE͕%#ίωΫγϣϯΛద੾ʹऔಘ͢ΔXSBQQFSΛ࢖͏͜ͱͰɺ BTZODUBTL಺͔Β%#Λฒߦʹ৮ΕΔΑ͏ͳղܾΛࢼΈͨɻ ଞʹԿ͔ྑ͍ΞΠσΞ͕͋Ε͹஌Γ͍ͨʜʜ 5ISFBEΛ࡞Δͱ'JCFSͷྑ͕͞ݮΔͷͰ
  15.  ϒϩοΧʔ৭ʑDPNNJUUFFHFN 6TBHF&YBNQMF ಺෦࣮૷ ؆ུ  if strea mi ng_response?(headers)

    response = Rack : : BodyProxy.ne w (response) do begin validate(request, status, headers, response) rescue = > e handle_exception(e, request.env) raise e if @raise end end else ಺෦తʹ3BDL#PEZ1SPYZΛ࢖༻ ৄ͘͠͸1VMM3FRVFTUΛࢀরͷ͜ͱ