Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
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.5k
タイムアウトにご用心 / 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.1k
Ruby で作る Ruby (物理)
mtsmfm
1
210
GraphQL Ruby benchmark
mtsmfm
1
820
Build REST API with GraphQL Ruby
mtsmfm
0
330
GraphQL Ruby をちょっとだけ速くした / Make graphql-ruby faster a bit
mtsmfm
1
730
Gaming PC on GCP
mtsmfm
0
730
How to introduce GraphQL to an existing React-Redux application
mtsmfm
1
250
Canary release in StudySapuri
mtsmfm
0
3.1k
Analyze Rails CI
mtsmfm
2
890
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
51
8.5k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Unsuck your backbone
ammeep
671
58k
Into the Great Unknown - MozCon
thekraken
40
1.9k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Visualization
eitanlees
146
16k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
How GitHub (no longer) Works
holman
314
140k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
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/