How it works...

The normal @Controller runs its request handler one thread at a time and uses only the default main thread of the application server. If a handler processes an HTTP request for a long period, the next transaction in the queue will be waiting for the main thread to be released from its current load. To avoid this starvation, Spring 5 still supports handlers that return WebAsyncTask<T>, Callable<T>, and DeferredResult<T>, which wrap a task and its result altogether to be executed by any of the threads generated by TaskExecutor, as authorized by DispatcherServlet.

If a request transaction returns a Callable<T>, Spring MVC coordinates with TaskExecutor and instructs it to create a thread for processing the Callable transaction. Then, the DispatcherServlet and all its Spring MVC components will exit to cater another request from the client but will wait for the response from that spawned thread. As more Callable tasks are processed by the @Controller, a number of threads will be running concurrently in the background that will eventually exit after its completion. The only problem with Callable<T> is the absence of callback methods that will synchronize its own thread executions.

Although it exhibits similar behavior and purposes to Callable, DeferredResult<T> contains callback methods that synchronize all running threads inside the task and propagate all the results before its task ends. Likewise, it has methods that save its state in a memory to be accessed by some threads during custom callbacks. If the requirement asks for an asynchronous @Controller to wait for all its subordinate thread executions to finish or to design a join() synchronization, it is recommended to wrap all its tasks in a DeferredResult<T> object.

To wrap Callable transactions with time constraints, we create a request handler that returns WebAsyncTask<T>. Once a controller returns a WebAsyncTask, the DispatcherServlet communicates with WebAsyncManager to process the wrapped Callable<T> given a timeout in milliseconds. Once the Callable task has been performed with or without errors, WebAsyncManager will dispatch the response to the Dispatcherservlet before it exits.

Relying on a synchronous @Controller when it comes to huge and slow request processes will cause performance degradation because it will produce a long queue waiting for the current request handler to complete its task, which means context switching from one request to another becomes expensive to client and server components.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.188.121