Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Fukuoka.rb_0x100_LT.pdf
Search
Yusuke Iwaki
May 11, 2022
Technology
480
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Fukuoka.rb_0x100_LT.pdf
Yusuke Iwaki
May 11, 2022
More Decks by Yusuke Iwaki
See All by Yusuke Iwaki
Playwrightのソースコードに見る、自動テストを自動で書く技術
yusukeiwaki
15
7.3k
あなたのWebサービスはAIに自動テストしてもらえる?アクセシビリティツリーで読み解く、AIの『視点』
yusukeiwaki
1
9.3k
個人開発から公式機能へ: PlaywrightとRailsをつなげた3年の軌跡
yusukeiwaki
12
9.2k
Capybara+生成AIでどこまで本当に自然言語のテストを書けるか?
yusukeiwaki
7
6k
ChatGPTを個々人が使っていた組織から チームチャットにボットを棲まわせて みんなが活用する組織になるまでの変遷 ぜんぶ紹介しちゃいます
yusukeiwaki
0
3.6k
E2E testing on Rails 2023
yusukeiwaki
4
3.6k
Railsの システムテスト解剖学
yusukeiwaki
8
8.2k
RailsのSystem specから 🎭Playwrightを使う
yusukeiwaki
2
16k
puppeteer-ruby: Ruby/Railsのためのブラウザオートメーションツール
yusukeiwaki
0
1.9k
Other Decks in Technology
See All in Technology
ソフトウェア ファクトリー - 再現性のあるソフトウェアの工場づくり / Software factory
iktakahiro
2
800
PagerDuty Tech Hub-鳴らすけれど、人は動かない
ezaki
0
120
触りたくないデータに、どう触るか AI時代のRBACアクセスガバナンス
ivry_presentationmaterials
0
140
事業活動を AI Ready にする攻めと守りのデータエンジニアリング / data-engineering-for-ai-ready-business
pei0804
7
2.7k
ブラウザとサーバーから考えるAI時代のフロントエンド監視
shogo4131
3
880
Jetson Orin Nanoとk3sとローカルLLMで音声文字起こしシステム作ってみた
y_sera15
0
120
Benchmarking Disaggregated Serving on vLLM + Dynamo with a Real Coding-Agent Workload
nttcom
0
120
実践! SRE × AI - ABEMA における AIOps -
tetsuya28
8
3k
FactoryBotアンチパターン / factory_bot anti-patterns
toshimaru
0
160
【Data Engineering Summit2026_登壇資料】医療ビッグデータ×AIエージェントを支えるデータ基盤とハーネスエンジニアリング
jmdc_presentation
0
140
アウトプット初心者、半年間のふりかえり
4o1sobblue
0
180
AIがコードを書く時代に、エンジニアは何で自分の価値を証明するのか / In an era where AI writes code how do engineers prove their value
carta_engineering
3
880
Featured
See All Featured
The Curse of the Amulet
leimatthew05
3
15k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
600
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
Mobile First: as difficult as doing things right
swwweet
225
10k
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
Transcript
async/await Rubyでどう書く? Fukuoka.rb 0x100 LT @YusukeIwaki
About @YusukeIwaki • 仕事:天神にある会社で、Railsアプリケーションの開発 ◦ 生まれは富山、大学は京都、1社目は札幌、2018年に福岡に移住 • puppeteer-rubyとかplaywright-ruby-clientとか作ってる人 ◦ ブラウザを自動操作するやつ
◦ Rubyでブラウザ操作するのに、Selenium以外の選択肢を作りたい。
Fukuoka.rb 0x0100回おめでとうございます • Kaigi on Rails 2021登壇のきっかけは、Fukuoka.rbの夜会 ◦ 夜の23時まで開いているRubyコミュニティは多分ここだけ? ◦
福岡にゆかりのあるひともないひともつながれるRubyコミュニティは素晴らしい ◦ 今後もゆるゆるとRubyを盛り上げていきましょう
本日の話 async / await ってRubyだとどうやって使えばいいの?
JSの有名ライブラリ Railsから使いたい! →Rubyに移植したい! async Promise then catch Promise.all Promise.race await
おそらく以下のどっちかが現実解 • 思考停止でconcurrent-rubyを使う ◦ とくにRailsアプリケーションだったら手軽 • めっちゃ考えてAsync gemを使う ◦ シングルスレッド動作で最大限のパフォーマンスが出せる
(memo) ここまで1分
おさらい: RubyのThreadとFiber • Thread→思考停止で、2つ以上の処理を同時に流せる • Fiber→ゆずりあいで、2つ以上の処理をかわりばんこに流す ◦ 合言葉は Fiber.yield
% ruby fiber.rb 0 1 2 3 4 0 1
2 3 4 % ruby thread.rb 0 0 1 1 2 2 3 3 4 4
async/await in Ruby • 思考停止でconcurrent-rubyを使う ◦ Threadベース ◦ とくにRailsアプリケーションだったら手軽 •
めっちゃ考えてAsync gemを使う ◦ Fiberベース ◦ シングルスレッド動作で最大限のパフォーマンスが出せる
(memo) ここまで2分半
concurrent-rubyでの async/await Promise Concurrent::PromisesモジュールのFutureを使う。 https://github.com/ruby-concurrency/concurrent-ruby/blob/master/docs- source/promises.in.md
concurrent-ruby: 2種類のFuture Concurrent::Promises.future { ….. ; 123 } • 裏で処理をやって、結果として123を返す
• Thread.newと同じ使い勝手で、さらに実行結果をもらえるイメージ f = Concurrent::Promises.resolvable_future, f.fulfill(123) , f.reject(err) • スレッドセーフな箱を作って、結果123を別スレッドから入れてもらう • JSのPromiseのような使い勝手
concurrent-ruby: Futureのチェーン、結果待ち受け future.then { |result| … ; next_result }.then {
|next_result| … } • JSのPromise#then, Promise#catch に限りなく近い future.value! • futureの結果をもらう。 • futureの結果がまだ出ていない場合には、結果が出るまでブロッキング。 Concurrent::Promises.zip(future1, future2, …) • 全部の結果が出揃うのを待つ。JSのPromise.allと同じ。
async click(x, y) { const point = await clickablePoint(x, y)
await scrollToPosition(x, y) await Promise.all([ mouse.down(x, y), mouse.up(x, y), ]) } def click(x, y) Concurrent::Promises.future do point = clickable_point(x, y).value! scroll_to_position(x, y).value! Concurrent::Promises.zip( mouse.down(x, y), mouse.up(x, y), ).value! end end concurrent-rubyを使ったasync/awaitっぽい実装 ※ 擬似コードです
でも気をつけろ!concurrent-rubyはThreadベースだ!
None
None
Async gem https://rubykaigi.org/2019/presentations/ioquatix.html
ノンブロッキングI/Oを活用し、IO待ちの間に別の処理を行う • シングルスレッドのFiberベースなので、オーバーヘッドが非常に少ない Ruby 2.xで利用するときには ノンブロッキングI/Oベースの各種ライブラリを併用する必要がある Async gem
Async { … } / Async::Reactor.run { … } •
処理のかたまり(task)を定義する ◦ JSの async () => { … } と似ている • トップレベルで利用するときと、ネストで利用するときとで挙動が違う ◦ トップレベルで利用時・・・サブタスクが全部終わるまで待つ ◦ ネストで利用時・・・サブタスクを作成し、スケジュール ◦ これも JSの async function呼び出しの挙動と似ている Async gemの基本
q = Async::Queue.new, q.dequeue, q.enqueue(hoge) • q.dequeueを呼ぶと、誰かがq.enqueueするまで待つ • q.dequeueよりも先に誰かがenqueue(hoge)していたら、即座にhogeが返る •
ほぼPromise cond = Async::Condition.new, cond.wait, cond.signal(hoge) • cond.waitを呼ぶと、誰かがcond.signalするまで待つ • cond.waitよりも先に誰かがcond.signal(hoge)しても、signalは捨てられる • 自前でPromiseっぽい何かを作る材料になる Async::Barrier, Async::Semaphore • サブタスク全部が終わるまで待つ、サブタスクの同時実行数を制限する • Promise.all 的なものを作る材料になる Async gemを使って async/await Promise
async click(x, y) { const point = await clickablePoint(x, y)
await scrollToPosition(x, y) await Promise.all([ mouse.down(x, y), mouse.up(x, y), ]) } def click(x, y) Async do point = clickable_point(x, y).wait scroll_to_position(x, y).wait barrier = Async::Barrier.new barrier.async { mouse.down(x, y).wait } barrier.async { mouse.up(x, y).wait } barrier.wait end end Async gemを使ったasync/awaitっぽい実装 ※ 擬似コードです
でも気をつけろ!Async gemはFiberベースだ! • 思考停止で使うと、並列処理されない(当然) • 不用意にwaitすると、メインスレッドがブロックされ全部が動かなくなる • Ruby 2.7で使いたいならノンブロッキングI/Oベースのライブラリ導入に そこそこ対応工数がかかる
ただ、用途があえば • すんごい速い • すんごい安定 ◦ 「ときどき処理順序がひっくり返ってしまって困る・・・」のような Threadベースだと起きる問題がFiberベースでは起きない
(memo) ここまで4分
まとめ:async/await in Rubyの現実解 • 思考停止でconcurrent-rubyを使う ◦ とくにRailsアプリケーションだったらもともと入ってるので手軽 ◦ Threadベースなので、処理順序性の保証とかほぼない •
めっちゃ考えてAsync gemを使う ◦ Fiberベースのシングルスレッド動作で最大限のパフォーマンスが出せる ◦ JSのasync functionに近い動作 ◦ Ruby 2.7環境で既存のアプリケーションに導入するのは結構たいへん
DEMO