| [//]: # " Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved. " | |
| [//]: # " " | |
| [//]: # " This program and the accompanying materials are made available under the " | |
| [//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at " | |
| [//]: # " http://www.eclipse.org/org/documents/edl-v10.php. " | |
| [//]: # " " | |
| [//]: # " SPDX-License-Identifier: BSD-3-Clause " | |
| Server Asynchronous Standalone Example | |
| ====================================== | |
| This example demonstrates Jakarta RESTful Web Services 3.0 asynchronous API, both on the client and | |
| server side. | |
| The goal of the sample is to demonstrate that with limited I/O processing threads | |
| on the server the synchronous execution of a long-running task may lead to resource | |
| starvation caused by I/O processing threads being blocked by the long-running | |
| operation, unable to serve new incoming requests. | |
| OTOH, when the same long-running operation is executed asynchronously, the I/O | |
| threads do not need to block while waiting for the long-running operation to finish | |
| and the overall throughput of the system is greatly increased. | |
| The example consists of 2 modules: | |
| 1. web application module "webapp" (produces server-async-standalone-webapp.war) | |
| - the module contains an long-running echo service deployed under application context root on path templates: | |
| - "long-running/sync/{echo}", served by a synchronously executed, blockingmethod. | |
| - "long-running/async/{echo}", served by an asynchronously executed, non-blocking method. | |
| 2. client module "client" (produces client.jar) | |
| - the module contains the web application client developed using the | |
| client API & leveraging the asynchronous client execution for spawning | |
| multiple simultaneous client requests with subsequent asynchronous response | |
| processing. | |
| To build the example, change to the example root directory and invoke maven build: | |
| > mvn clean package | |
| This command builds the web application WAR as well as client JAR artifacts. Once | |
| built, the web application may be deployed to the application server. E.g. to deploy | |
| the application to a running GlassFish instance, you may do (while still being in | |
| the root example directory): | |
| > $AS_HOME/bin/as-admin deploy ./webapp/target/server-async-standalone-webapp.war | |
| Once deployed, the client can be run as follows: | |
| > cd client | |
| > mvn exec:java | |
| This will start the main client GUI window. In the top panel, the GUI lets you to customize | |
| few variables such as number of requests to be sent, base web application URL or sync/async | |
| endpoint to be invoked. Once the client is set up, the "Run" button runs the requests. Each | |
| request is represented as a colored box in the lower window panel. The color indicates the | |
| request status: | |
| * yellow - running | |
| * green - successfully completed | |
| * red - request execution failed with an error | |
| Also, the tooltip of each box provides additional status information. After the execution is | |
| finished, short statistics about the run are displayed in the middle window panel. | |
| Executing command-line client: | |
| ------------------------------ | |
| Optionally, a command line Main.java client can be executed (by changing the mainClass of | |
| exec-maven-plugin in pom.xml to org.glassfish.jersey.examples.server.async.Main). | |
| Following properties may be customized in the command-line client runtime: | |
| 1. req=<n> | |
| : number of requests to be sent by the client, defaults to 10 | |
| 2. mode=(sync|async) | |
| : execution mode defines which version of the service should be used, defaults to "async" | |
| 3. uri=<base_webapp_uri> | |
| : base URI of the deployed web application, defaults to "http://localhost:8080/server-async-standalone-webapp" | |
| These properties may be passed throug maven to the client runtime as command-line arguments | |
| using the -Dexec.args="<arguments>" flag, e.g.: | |
| > mvn exec:java -Dexec.args="req=20 mode=sync uri=http://foo.com/bar" | |
| When the example client is run, successfully executed requests are output as an | |
| asterisk '*', failed requests as an exclamation mark '!'. Any errors that occured | |
| during the client execution are reported at the end of the run including the | |
| statistics about the processing time and success ratio. | |
| Try running the client using many requests and compare the results when running | |
| against sync and async version of the resource, e.g.: | |
| > mvn exec:java -Dexec.args="req=100 mode=sync" | |
| > mvn exec:java -Dexec.args="req=100 mode=async" | |
| You should see a significant speed improvement in the latter run. |