Using Asynchronous Servlets and the behaviour of dispatch() and complete() methods while processing request

后端 未结 1 934
你的背包
你的背包 2021-02-20 16:13

I am using Asynchronous Servlets to process requests,

According to Docs:(complete(),dispatch())

╔══════════════════╦═════════════════════════════════════         


        
1条回答
  •  情歌与酒
    2021-02-20 17:04

    From the horse's mouth (Oracle Javadoc)

    complete()

    Completes the asynchronous operation that was started on the request that was used to initialze this AsyncContext, closing the response that was used to initialize this AsyncContext.

    Any listeners of type AsyncListener that were registered with the ServletRequest for which this AsyncContext was created will be invoked at their onComplete method.

    dispatch(String path)

    Dispatches the request and response objects of this AsyncContext to the given path.

    ...

    Control over the request and response is delegated to the dispatch target, and the response will be closed when the dispatch target has completed execution, unless ServletRequest#startAsync() or ServletRequest#startAsync(ServletRequest, ServletResponse) are called.

    Q/A

    1. what's the difference between dispatch and complete?

      Calling complete tells container to fire onComplete listeners and stop the asynchronous mode, dispatch basically tells container to call complete and then forward the request (internally) to the specified path. The path can be a JSP, a synchronous servlet or even another asynchronous servlet that will trigger a new round of async processing.

    2. When I called dispatch inside run the response reached the client, does that mean we can push the response asynchronously like this?

      On the contrary dispatch closes the asynchrnonous mode and forwards the request to another servlet or JSP. To push data to the client you have to write to Response object associated with the AsyncContext.

    3. if I call dispatch first and complete next what is the behaviour of the thread ?

      Undefined, which is a nice way of saying it depends on how the container is implemented. Maybe it will throw an error, maybe onComplete handlers will be fired twice, maybe call to complete will do nothing, maybe there will be a race condition between your thread and the container in calling handlers and manipulating internal structures of AsyncContext implementation etc.

    4. If I call any method after complete what will happen to that method call

      Depends on what method you are calling. The specification states that dispatch will throw IllegalStateException if called after complete, anything else is undefined and thus implementation specific.

    5. If I am calling asynchronous methods inside run should I call complete inside callback()?

      Yes you have to call complete to finish asynchronous processing once you are done. The run method is used to schedule a task to be executed by a container managed thread pool and it can be called multiple times during the lifetime of an asynchronous request.

    6. Are there any examples of using Async Servlets and Futures Combination?

      I am not aware of any, but there are a few good examples of using async servlets linked in "See also" section. In principle I don't see much value in using futures. See: "Is async servlet a good fit for what I am doing?"

    Is async servlet a good fit for what I am doing ?

    The objective of an async servlet is to reduce the number of threads required to serve certain types of "push clients": HTTP request is left open until an (usually external) event occurs and then the server will push data down the channel. In a standard servlet environment each client will have a dedicated thread allocated and waiting thus consuming valuable system resources. In asynchronous mode the client connection can be put "on hold" and detached from an execution thread until an event comes in which makes it possible to do something with it. Think about an online chat application as an example. All connected clients will be idle until someone posts a message to the room. It is wasteful to keep a dedicated thread for every connected user.

    If your application needs to call multiple services at the same time and you wish to use futures and executors to parallelize that operation then an asynchronous servlet is probably not a good fit: You will gain nothing and a standard servlet will be much easier to implement. On the other hand if service calls can be made in an asynchronous (non-blocking) way, without relying on threaded executors, then it's another story.

    The "right" question to ask is: Do I want to have fewer threads than active connections?


    See also:

    • A state diagram in AsyncStateMachine javadoc (Tomcat implementation).
    • https://blogs.oracle.com/enterprisetechtips/entry/asynchronous_support_in_servlet_3
    • Servlet-3 Async Context, how to do asynchronous writes?

    0 讨论(0)
提交回复
热议问题