Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upgrade filters to support Servlet 3.0 asynchronous servlet

I have a servlet which is used to fetch data from many third party REST datapoints, integrate all the data and report the data in a HTML format. I also have a filter which has the following flow -

  1. Create an event record when the request hits the filter and add the eventrecord object to the request
  2. perform chain.doFilter - which allows the servlet to add more details to the eventrecord
  3. on the way back to the browser, filter gets the eventrecord object and logs it.

Now if I use Asynchronous servlet using AsyncContext context = request.getAsyncContext();, which will talk to the same REST datapoints but as and when data is ready, it will write to the response stream instead of waiting for all the REST data points to respond, how would I re write my filter ? Would it be attached to the thread which is responsible for flushing data from the REST data points so that once all the data is processed and flused, it will log the eventrecord ? Is there any common pattern that I can study to understand how such use cases can be handled with Servlet 3.0's asynchronous servlets ? I am using JDK 6.0, Tomcat 7.0.

like image 533
Shamik Avatar asked May 28 '12 21:05

Shamik


2 Answers

Just add @WebFilter(urlPatterns = {"/*" }, asyncSupported = true) in web-xml for your filter.

Or add <async-supported>true</async-supported>

like image 71
Tim Avatar answered Nov 07 '22 12:11

Tim


I have put a bounty as I'm unsure myself how to properly support instrumenting or diagnostic filters (e.g. Codahales metrics filters).

While adding <async-supported>true</async-supported> to your filters will certainly make them appear to work it may not get the results you expect (in the case of metrics all your requests will appear to be very fast).

It may seems like a good idea to get the AsyncContext right away in the filter to bind metric data but various containers apparently have issues with this and I believe frameworks like Spring have issues as well (this might just be my older version of Spring). That is most frameworks expect the first half of the request handling to be synchronous (I maybe massively wrong on this).

Consequently it seems like the only fool proof way is to integrate filters at the framework level. For example Spring offers org.springframework.web.context.request.async.DeferredResultProcessingInterceptor which is somewhat analogous to the AsyncContext events.

This is somewhat unfortunate as not all request maybe handled by the web framework but then again there is difference between handling the first portion of the request and actually fulfilling (ie that is now two metrics you might want to monitor).

like image 24
Adam Gent Avatar answered Nov 07 '22 14:11

Adam Gent