Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Servlet と Future
の関わり方
Kazuhiro Sera @seratch_ja
2015/08/01
自己紹介
•東京から来ました
•@seratch / @seratch_ja
•ScalikeJDBC(2011 ∼)
•Skinny Framework(2013 ∼)
•Scalatra、json4s、Scalate メンテナ
•エムスリー...
アジェンダ
•前提・背景
•スレッドローカルが存在する世界
•Future はスレッドプールが裏にいる
•Servlet API の mutability
•Async モードでの request リサイクル問題
•Scalatra の Dyn...
前提・背景
2 つのパターン
•メインスレッドから Future を複数投げて
Await.result(Future) で待ち合わせ、同期で
Servlet response を返す
•Servlet 3 からの async mode により非同期
で ...
なぜ Future か
•Servlet において Scala の Future を積極的に
使っていく必要性は特にない
•とはいえ 2.10 から入った Future は十分に普
及してきた、Future を返す実装の組み込みに
対応できない...
スレッドローカル
が存在する世界
スレッドモデル
•request を受けて response を返すスレッド
•HTTP レスポンス返すまでメインスレッドだけ
で処理するのが基本的なスタイル
•このメインスレッドは Servlet コンテナが持つ
スレッドプールで管理される
...
スレッドローカル
•Scala では DynamicVariable
•シングルスレッドで完結する前提ならスレッド
ローカルを使って色々楽ができる
•状態をパラメータで引き回さない
•AOP で透過的な処理をはさみこみやすい
•暗黙の状態を活用...
Future は
スレッドプールが
裏にいる
Future
•Future scaladoc
•Future.apply { ここは別スレッド }
•Future.successful { ここは同じスレッド }
•カジュアルに別スレッドの処理が生まれる、適
当にやってもスレッドプール
(...
Servlet API の mutability
mutability
•request#setAttribute(String, AnyRef) を始
めとする setter メソッド
•request attributes に依存する実装パターン
•session などコンテナ管理のオブジ...
Async モードでの
request リサイクル問題
JSR 340: Java Servlet 3.1 Specification
https://jcp.org/en/jsr/detail?id=340
Bug 433321 - request.getContextPath() is null when working in async mode
https://bugs.eclipse.org/bugs/show_bug.cgi?id=433...
Bug 46792 - NullPointerException in org.apache.catalina.connector
https://bz.apache.org/bugzilla/show_bug.cgi?id=46792#c5
...
JSR 340: Java Servlet 3.1 Specification
https://jcp.org/en/jsr/detail?id=340
recycling objects
•実際の挙動として request は
AsyncContext#complete() が呼ばれる前に
recycle されることがある
•パフォーマンス上のオーバーヘッドを避けるた
め複数の Servlet...
Scalatra の
DynamicScope 問題
この Servlet 上で作られた
Future のスレッド内も含め
どこからでもこの request に
気軽にアクセスできてしまう
request/response
•Scalatra の request/response はスレッドロー
カル、Future 側からそのまま触れない
•implicit パラメータで引き渡すアプローチにす
べての DSL、拡張が対応していない...
Skinny 2 での
ソリューション
Skinny 2.0
skinny-engine
skinny-engine
•Scalatra を fork して DSL の互換性は維持し
つつ、内部実装を大きく変えた
•trait の構成はあまり互換性を維持していない
(改名・構造の変更・削除)
•Scalatra の既存のテストをほぼ...
stable request
stable request
•request を Future が処理中のタイミングで
recycle されたとしても read-only な情報、
request attributes 等へのアクセスを保証
•request attribu...
No more DynamicScope
No more DynamicScope
•前提として、すべての DSL に Context を
implicit parameter として渡す
•Context を引数にとる関数をアクションとして
とる AsyncSkinnyEngineS...
New async trait
Scalatra compatible trait
話したこと
•前提・背景
•スレッドローカルが存在する世界
•Future はスレッドプールが裏にいる
•Servlet API の mutability
•Async モードでの request リサイクル問題
•Scalatra の Dyn...
ハンズオンの宣伝
Minimum Skinny 2 App
おそらく一番簡単な
Scala Web アプリ実装
13:30 ∼ @第4会議室
•これから Scala を始めたい方向けです
•Servlet に馴染みがあるなら、まず Skinny で
Scala を始めてみましょう
•安定版の 1.3 or skinny-engine-server で
•...
おおきに :)
Servlet と Future の関わり方 #scala_ks
Upcoming SlideShare
Loading in …5
×

Servlet と Future の関わり方 #scala_ks

6,227 views

Published on

English version is here: http://www.slideshare.net/seratch/future-on-servlet-scalaks

http://summit.scala-kansai.org/ でのプレゼンです

Published in: Technology
  • Be the first to comment

Servlet と Future の関わり方 #scala_ks

  1. 1. Servlet と Future の関わり方 Kazuhiro Sera @seratch_ja 2015/08/01
  2. 2. 自己紹介 •東京から来ました •@seratch / @seratch_ja •ScalikeJDBC(2011 ∼) •Skinny Framework(2013 ∼) •Scalatra、json4s、Scalate メンテナ •エムスリー株式会社 ソフトウェアエンジニア
  3. 3. アジェンダ •前提・背景 •スレッドローカルが存在する世界 •Future はスレッドプールが裏にいる •Servlet API の mutability •Async モードでの request リサイクル問題 •Scalatra の DynamicScope 問題 •Skinny 2 でのソリューション
  4. 4. 前提・背景
  5. 5. 2 つのパターン •メインスレッドから Future を複数投げて Await.result(Future) で待ち合わせ、同期で Servlet response を返す •Servlet 3 からの async mode により非同期 で Servlet response を返す(今日のテーマは 主にこっち)
  6. 6. なぜ Future か •Servlet において Scala の Future を積極的に 使っていく必要性は特にない •とはいえ 2.10 から入った Future は十分に普 及してきた、Future を返す実装の組み込みに 対応できないと実用上困るケースがある •身近な具体例では nulab/scala-oauth2- provider を使うにあたり、支障があった
  7. 7. スレッドローカル が存在する世界
  8. 8. スレッドモデル •request を受けて response を返すスレッド •HTTP レスポンス返すまでメインスレッドだけ で処理するのが基本的なスタイル •このメインスレッドは Servlet コンテナが持つ スレッドプールで管理される •JavaEE 7 は JSR-236 でコンポーネント管理 と非同期処理を両立するための仕様を提示
  9. 9. スレッドローカル •Scala では DynamicVariable •シングルスレッドで完結する前提ならスレッド ローカルを使って色々楽ができる •状態をパラメータで引き回さない •AOP で透過的な処理をはさみこみやすい •暗黙の状態を活用、コードがシンプルに
  10. 10. Future は スレッドプールが 裏にいる
  11. 11. Future •Future scaladoc •Future.apply { ここは別スレッド } •Future.successful { ここは同じスレッド } •カジュアルに別スレッドの処理が生まれる、適 当にやってもスレッドプール (ExecutionContext で指定)で管理される •Future を生んだ元スレッドの値を Future 側 のスレッドから簡単に参照できてしまう(後述)
  12. 12. Servlet API の mutability
  13. 13. mutability •request#setAttribute(String, AnyRef) を始 めとする setter メソッド •request attributes に依存する実装パターン •session などコンテナ管理のオブジェクト •任意のタイミングで response を出力 •マルチスレッドでアクセスする場合、素のまま で扱うのはあやうい
  14. 14. Async モードでの request リサイクル問題
  15. 15. JSR 340: Java Servlet 3.1 Specification https://jcp.org/en/jsr/detail?id=340
  16. 16. Bug 433321 - request.getContextPath() is null when working in async mode https://bugs.eclipse.org/bugs/show_bug.cgi?id=433321 Jetty
  17. 17. Bug 46792 - NullPointerException in org.apache.catalina.connector https://bz.apache.org/bugzilla/show_bug.cgi?id=46792#c5 Tomcat
  18. 18. JSR 340: Java Servlet 3.1 Specification https://jcp.org/en/jsr/detail?id=340
  19. 19. recycling objects •実際の挙動として request は AsyncContext#complete() が呼ばれる前に recycle されることがある •パフォーマンス上のオーバーヘッドを避けるた め複数の Servlet コンテナに共通する挙動 •Servlet の仕様に response についても同様の 記述(5.7)はあるが、少なくとも stateless な HTTP 通信に関しては close まで維持され ると考えてよいはず
  20. 20. Scalatra の DynamicScope 問題
  21. 21. この Servlet 上で作られた Future のスレッド内も含め どこからでもこの request に 気軽にアクセスできてしまう
  22. 22. request/response •Scalatra の request/response はスレッドロー カル、Future 側からそのまま触れない •implicit パラメータで引き渡すアプローチにす べての DSL、拡張が対応していない、意図せ ず DynamicScope が呼び出される •最初期の目的・設計は妥当だった(Future は まだメインストリームでなかった、模倣した Sinatra は Rack アプリ)
  23. 23. Skinny 2 での ソリューション
  24. 24. Skinny 2.0
  25. 25. skinny-engine
  26. 26. skinny-engine •Scalatra を fork して DSL の互換性は維持し つつ、内部実装を大きく変えた •trait の構成はあまり互換性を維持していない (改名・構造の変更・削除) •Scalatra の既存のテストをほぼそのままの状 態ですべて pass している •改善アイデア、潜在的問題の発見があった、 Scalatra にもフィードバックしていきたい
  27. 27. stable request
  28. 28. stable request •request を Future が処理中のタイミングで recycle されたとしても read-only な情報、 request attributes 等へのアクセスを保証 •request attributes の更新も考慮 •コンテナ管理オブジェクトの操作はメインスレッ ド以外ではアクセスエラーに(2.0.0.M3) •少なくとも Jetty、Tomcat で動作保証
  29. 29. No more DynamicScope
  30. 30. No more DynamicScope •前提として、すべての DSL に Context を implicit parameter として渡す •Context を引数にとる関数をアクションとして とる AsyncSkinnyEngineServlet/Filter •Scalatra 互換な trait では error: ambiguous implicit values (コンパイルエ ラー)を発生させて確実に潰す
  31. 31. New async trait
  32. 32. Scalatra compatible trait
  33. 33. 話したこと •前提・背景 •スレッドローカルが存在する世界 •Future はスレッドプールが裏にいる •Servlet API の mutability •Async モードでの request リサイクル問題 •Scalatra の DynamicScope 問題 •Skinny 2 でのソリューション
  34. 34. ハンズオンの宣伝
  35. 35. Minimum Skinny 2 App おそらく一番簡単な Scala Web アプリ実装
  36. 36. 13:30 ∼ @第4会議室 •これから Scala を始めたい方向けです •Servlet に馴染みがあるなら、まず Skinny で Scala を始めてみましょう •安定版の 1.3 or skinny-engine-server で •作者なので使い方の質問すぐ答えます •13:30 - 第 4 会議室でお待ちしています
  37. 37. おおきに :)

×