3. Agenda
•Why Future
•Thread local things in the wild
•Future has its own thread pool
•Servlet API s mutability
•recycling request issue in async mode
•Scalatra DynamicScope issue
•Skinny 2 s solution
5. How to use Future
•1) Creating and composing multiple
Futures and then Await.result(Future),
returning Servlet response synchronously
•2) Running Servlets in async mode
supported since Servlet 3
6. Why Future
•Using Future on Servlet is not always
recommended
•OTOH, Future is the standard in Scala
now, sometimes needed to smoothly
integrate Future-based libraries
•My near affair: using nulab/scala-oauth2-
provider in a Servlet application
8. Threaded model
•one thread for one request
•A thread returns a response for a request
•On the same thread for whole process
•Thread pool managed by containers
•JavaEE 7 has JSR-236 to show how to use
concurrency
9. ThreadLocal
•DynamicVariable in Scala
•Sometimes have an easy time of it by
using ThreadLocal if no multithreading
•No need to take state around to methods
•AOP friendly
•Implicit state makes code simple
11. Future
•Future scaladoc
•Future.apply { different thread here }
•Future.successful { same thread here }
•Can easily create async operations that
run on different threads managed by
thread pool (ExecutionContext)
•Too easy to access fields on the Servlet
thread from Future threads
13. Servlet API is mutable
•Request#setAttribute(String, AnyRef)
•Implementation patterns that depend on
request attributes
•Objects managed by containers
•Writing result value on response any time
•Simply accessing them among multiple
threads is so fragile
19. recycling requests
•In fact, request can be recycled before
AsyncContext#complete()
•Containers commonly do the recycle in
order to avoid performance overhead
•If I understand right, even though Servlet
spec says same about response (5.7),
response won t be recycled until its
closure at least in cases of stateless HTTP
21. Too easy to access this value
everywhere including Future
threads created on this Servlet
22.
23. request/response
•ScalatraBase s request/response are
thread local, too dangerous to access
them from Future threads
•All the DSL and extensions don t accept
request as implicit parameter
•In the initial state, this design is
reasonable (Future didn t exist at the time,
Sinatra concept)
27. skinny-engine
•Started as a Scalatra fork, much improved
internal code while DSL source
compatibility is kept
•Many renaming/re-packaging and a few
removal on traits
•Passed all the Scalatra s existing tests
•I d love to contribute skinny-engine s
improvements to Scalatra too
29. stable request
•Stable access to read-only data, request
attributes even when request has been
recycled while Future ops are still running
•Validates unstable access to objects
managed by containers (2.0.0.M3)
•Should work at least on Jetty and Tomcat
31. No more DynamicScope
•Pass skinny.engine.Context as implicit
parameter to all the DSL APIs
•AsyncSkinnyEngineServlet/Filter accept
(Context) => Any as action instead
•On Scalatra compatible traits, detect
fragile code by checking compilation
errors: error: ambiguous implicit values