I am the senior IT manager at the Macau Productivity and Technology Transfer Center. I've written popular books on agile and web technologies and created an open source testing library for Wicket. kent is a DZone MVB and is not an employee of DZone and has posted 7 posts at DZone. You can read more from them at their website. View Full User Profile

Implementing an async servlet in Scala with less than 10 lines of code

01.11.2012
| 4507 views |
  • submit to reddit

What is async servlet and why use it? An async servlet can tell the container that it will handle a request later, so that the current thread is not tied up and can be used for another request. Why is it useful? For example, if the request is going to do something relatively time consuming (e.g., generating a report from a DB), instead of tying up the thread doing nothing waiting for the data, you can free up the thread for other requests and wait for the data in a background thread. When the data is received, you can complete the response.

It turns out to be very easy to implement an async servlet (new in servlet 3.0). In Scala, it took less than 10 lines of code (not counting brace brackets and imports):

package com.ttdev.webqos
import javax.servlet.http._
import java.util.concurrent._
 
class MyServlet extends HttpServlet {
  private val pool = Executors.newFixedThreadPool(1) // create a thread pool
 
  override def doGet(req: HttpServletRequest, res: HttpServletResponse) {
    req.startAsync  //tel the container the response will be generated later
    pool.execute(new Runnable() {  // add the runnable to the queue
      def run {  // when a thread in pool picks up the runntable...
        res.getWriter.append("hello world!")  // write the response
        req.getAsyncContext.complete  // tell the container that the response is done
      }
    })
    // return without a response yet
  }
 
}

 

From http://agileskills2.org/blog/2012/01/03/implementing-an-async-servlet-in-scala-in-less-than-10-lines/

Published at DZone with permission of kent tong, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Tomasz Nurkiewicz replied on Wed, 2012/01/11 - 12:21pm

You can save extra few lines by using implicit conversion from any code block to Runnable:

 

implicit def fun2Runnable[T](f: => T) = new Runnable {
	def run() {
		f
	}
}

This simplifies your code to:

pool.execute({
	res.getWriter.append("hello world!")
	req.getAsyncContext.complete()
})

Also in Scala using actors would probably be more idiomatic approach to asynchronous processing.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.