Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
タイムアウトにご用心 / Timeout might break application state
Search
Fumiaki MATSUSHIMA
October 10, 2021
6
2.6k
タイムアウトにご用心 / Timeout might break application state
https://kaigionrails.doorkeeper.jp/events/127339
Kaigi on Rails _2021_ new LT 発表資料
Fumiaki MATSUSHIMA
October 10, 2021
Tweet
Share
More Decks by Fumiaki MATSUSHIMA
See All by Fumiaki MATSUSHIMA
Learning from performance improvements on GraphQL Ruby
mtsmfm
1
1.2k
Ruby で作る Ruby (物理)
mtsmfm
1
230
GraphQL Ruby benchmark
mtsmfm
1
860
Build REST API with GraphQL Ruby
mtsmfm
0
360
GraphQL Ruby をちょっとだけ速くした / Make graphql-ruby faster a bit
mtsmfm
1
760
Gaming PC on GCP
mtsmfm
0
760
How to introduce GraphQL to an existing React-Redux application
mtsmfm
1
270
Canary release in StudySapuri
mtsmfm
0
3.2k
Analyze Rails CI
mtsmfm
2
960
Featured
See All Featured
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
34k
[RailsConf 2023] Rails as a piece of cake
palkan
58
6.2k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
Typedesign – Prime Four
hannesfritz
42
2.9k
Embracing the Ebb and Flow
colly
88
4.9k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
Docker and Python
trallard
47
3.7k
Become a Pro
speakerdeck
PRO
31
5.7k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.8k
Being A Developer After 40
akosma
91
590k
Transcript
@mtsmfm タイムアウトにご用心
松島 史秋 GitHub, Twitter @mtsmfm
https://ninirb.github.io
https://www.meetup.com/ja-JP/GraphQL-Tokyo/
伝えたいこと タイムアウトしたプロセスを再利 用してはいけない
どんな問題が起きるか - タイムアウト後、アプリケーションの状態が崩壊 する可能性がある
User.where(name: "foo").not_deleted /users_count /users?name=foo User.not_deleted.count
User.where(name: "foo").not_deleted /users_count 1. リクエストがくる /users?name=foo User.not_deleted.count
User.where(name: "foo").not_deleted /users_count User.not_deleted.count 1. リクエストがくる 2. not_deleted scope を組み立
て中にタイムアウトになる /users?name=foo
User.where(name: "foo").not_deleted /users_count 1. リクエストがくる 2. not_deleted scope を組み立 て中にタイムアウトになる
/users?name=foo 3. 別のリクエストがくる User.not_deleted.count
User.where(name: "foo").not_deleted /users_count 1. リクエストがくる 2. not_deleted scope を組み立 て中にタイムアウトになる
4. タイムアウトしたときにスタックされ ていた where が適用される /users?name=foo 3. 別のリクエストがくる User.where(name: "foo").not_deleted.count User.not_deleted.count
どんな問題が起きるか - タイムアウト後、アプリケーションの状態が崩壊 する可能性がある - タイムアウトのタイミング次第では、その瞬間の状態が 保持されてしまうケースがある - 例えば、User.count と書いてあるのに、タイムアウト以
後、そのプロセスは User.where(name: "foo").count 相当の処理をする
なぜそうなるのか - ensure 中に Thread#raise されるとそこで ensure が全部実行されることなく終わってしま うから
class Stack def stack @stack ||= [] end def with(name)
stack.push(name) yield stack ensure stack.pop end end stack = Stack.new stack.with('foo') do p stack.stack #=> ["foo"] stack.with('bar') do p stack.stack #=> ["foo", "bar"] end p stack.stack #=> ["foo"] end
ここでタイムア ウトしても セーフ class Stack def stack @stack ||= []
end def with(name) stack.push(name) yield stack ensure stack.pop end end
ここでタイムア ウトすると pop されない class Stack def stack @stack ||=
[] end def with(name) stack.push(name) yield stack ensure stack.pop end end
Rails のバグ? - 違う - あらゆるタイミングで Thread#raise されること を考慮するのは厳しいので諦めている -
https://github.com/rails/rails/pull/17607#issuecomme nt-70538060 - Scope 以外にも ensure で状態をリセットすると ころはタイムアウトで壊れる可能性有
どんなときに踏みやすいか - 自分で Timeout.timeout を書くことはそんなに ない気がする - 注意すべきは gem、特に Web
サーバとか Rack middleware とか
rack-timeout の罠 - rails new して書かれている Puma にはタイム アウト機構はなく、rack-timeout が事実上デファ
クト - Heroku のチュートリアルでも紹介されていたり - デフォルト設定だとまさにやばいケースに該当 する
rack-timeout の罠 - term_on_timeout: true にすれば、タイムアウト したら TERM で殺してくれる -
これはデフォルトではない - Puma を Clustered mode で動かしていない場合、true にするとサーバが完全に死ぬ
https://github.com/sharpstone/rack-timeout/issues/169
デフォルトやばいのでは? - 警告だけでも提案したが通らなかった - rack-timeout gem が歴史的に TERM するわけではな い
- 危ないという説明も既にある (doc/risks.md) - Puma のデフォルトは Clustered mode じゃない
伝えたいこと - タイムアウトしたプロセスを再利用してはいけな い - Middleware っぽいところでやってると特に危ない - rack-timeout は
term_on_timeout を必ず true に - 具体的な再現コードなどは https://zenn.dev/mtsmfm/articles/d55d739104e87c
Credits Background pattern from Toptal Subtle Patterns https://www.toptal.com/designers/subtlepatterns/