|  | [//]: # " 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. |