Articles
Java Platform, Standard Edition
|
|
| By Nagendra Nagarajayya, Ashish Bannerjee, Ranjan Kumar, Vikas Gera, Gayathry Manikandan and Dmitry Isakbayev, October 2007 |
|
The Long Running Web Process (LRWP) is a protocol used by a web server to communicate with its peers. LRWP is similar to CGI, but faster, since the peer is persistent across requests. In LRWP, a TCP connection is established between the LRWP peer and a LRWP agent. The LRWP agent could be the web container or a process running within the web container and the LRWP peer could be any process running on a network. The LRWP peer at connection registers the web context that the peer is interested in. The web context could be any context, such as "/osp", "/tep", or "/cgi-bin" itself. When a request for that context is made, the agent transfers the input to the LRWP peer and sends the output from the peer back to the web client. The LRWP agent should also be able to support multiple peers concurrently, and each peer makes a connection and registers the context it is interested in.
A web server that implements LRWP protocol listens on a TCP/IP port, 1081 default, for LRWP peers to connect. A peer connects by opening a TCP/IP connection and sending in the context name and an optional host name. The host name is to support virtual host names. The peer then waits for a response from the web server, which is an OK to indicate a connection registration or an error message. After a successful registration, the peer then waits for requests from the web server. The web server sends in environment variables such as the cgi-bin request and the data, and waits for a response from the peer. The peer responds by sending in environment variables such as a cgi-bin program response and the data. The connection is terminated by the web server or the peer by closing the TCP/IP connection. The details of the protocol implementation can be found on the Xitami page, "Extending Xitami with External peer Processes".
Xitami is a lightweight, multithreaded, ServerWatch's hall of fame web server. It supports the following features:
The design for implementing the LRWP protocol in the Java platform uses a servlet container to handle HTTP requests and also to make use of servlets to handle the LRWP processing. The initial idea was to build a multithreaded LRWP Agent server, running within the servlet container, which would act as a broker between the LRWP peers and the servlets. It would accept requests from LRWP peers, pass on the incoming HTTP requests to the peers, and pass the response from the peers back to the servlets. On an HTTP request, the servlet would communicate the HTTP request to the LRWP agent, which would block the servlet thread, unblock the the peer thread, and pass on the request to the LRWP peer. Then, the response from the peer would be passed back to the servlet by waking it up and blocking the peer thread. This design was modified so that instead of having a multithreaded LRWP agent, we had a single threaded agent, which accepted the connection request from a LRWP peer and stored the connection in a ContextAssistantManager. Instead of blocking while passing on the request to the Agent, the servlet thread instead now looked up the connection to the peer using the ContextAssistantManager and passed on the HTTP request after transforming it to the LRWP protocol itself, waiting for a response from the LRWP peer, and then returning the response as its own.
Salient features of this design are:
LRWPAgentManager, and the RequestHandler are made transparent through the use of interfaces.Interface Classes
LRWPAgentManager LRWPAgentManager implementation Class. |
Methods
|
Description
|
|
|---|---|---|
start() |
Starts the
LRWPAgentManager. |
|
setNumOfAgents |
Defines the number of agents that would run.
|
|
setStartPort() |
Defines the starting port to which LRWP agent instances would bind. For example, if the starting port is defined to be 1081 and number of agents is 2, then two instances of LRWP agent would start up - first binding to port 1081 and second binding to port 1082.
|
|
LRWPAgentRegistrar LRWPAgentRegistrar Implementation Class. |
Methods
|
Description
|
|---|---|
register() |
Register the Proxy Service Instance (LRWP
RequestHandler). |
deregister() |
De-register the Proxy Service Instance (LRWP
RequestHandler) |
HttpProxyService RequestHandler Class. |
Methods
|
Description
|
|---|---|
service() |
Implement the request service algorithm in this method.
|
stop() |
Method to stop the RequestHandler/Proxy service instance.
|
Classes
HttpProxyServlet servlet which implements following servlet methods: |
Methods
|
Description
|
|
|---|---|---|
init() |
Reads initialization parameters from the
servlet deployment file (web.xml) and performs initialization of variables. It also creates an instance of LRWPAgentProxyManager, after fetching the implementation class name from the deployment parameter 'Proxy Manager'. |
|
destroy() |
Stops the
LRWPAgentProxyManager instance and disposes of/destroys the servlet. |
|
processRequest() |
This method is invoked to service the HTTP Request. This method forwards/delegates the request to the
LRWPAgentManager. Now the LRWPAgentProxyManager responds to this request. |
|
LRWPAgent (web.xml). If multiple instances of LRWP agents are defined in the configuration file, then the port defined in web.xml is the starting port. When a new LRWP peer Process connects to an LRWP agent instance, it creates a RequestHandler instance and again waits for a new LRWP peer. This class implements the following methods: |
Methods
|
Description
|
|---|---|
run() |
This is the thread class method overridden by the LRWP agent Class. The LRWP agent binds itself to the server port defined in the configuration file, and waits for the peer process. As soon as the peer process opens a connection with the LRWP agent, it instantiates an LRWP
RequestHandler. |
stopThread() |
Stops the LRWP agent server thread and closes the socket port for communication.
|
LRWPAgentProxyManager (url) of a virtual host. This class implements the LRWPAgentManager and LRWPAgentRegistrar interfaces. It has following methods: |
Methods
|
Description
|
|
|---|---|---|
start() |
Creates instance(s) of
LRWPAgent class and starts LRWP agent thread(s). |
|
stop() |
Stops the LRWP agent instance(s).
|
|
setNumOfAgents() |
Sets the number of agents to be started.
|
|
setStartPort() |
Defines the starting port on which LRWP agent would be started. If a new instance of LRWP agent is created, it would bind with a new port (starting port + n).
|
|
register() |
Creates an entry in the repository for a virtual host, path and LRWP
RequestHandler (implementor of Service Class interface). |
|
deregister() |
Removes a virtual host, path and LRWP
RequestHandler entry from the repository. |
|
Service() |
This method implements the logic to get a
RequestHandler instance which would serve the client request. If there is no instance of RequestHandler to support the request, or it is busy, the request would be put to wait, or would result in a default response. |
|
LRWP RequestHandler RequestHandler is bound to only one LRWP peer over socket connection. One LRWP peer process may be connected to multiple request handler instances over multiple socket connections. This class implements the HttpProxyService interfaces. It implements the following methods: |
Methods
|
Description
|
|---|---|
init() |
Receives and acknowledges the init message from the LRWP peer, which contains information about the virtual host and the path it will serve. Acknowledgment begins with "OK" if the init method is successfully received from the LRWP peer process, or else the acknowledgment contains "ERROR" as the starting string.
|
service() |
This is the main method that does the transformation of the HTTP Request to the LRWP Request. The request is sent to the LRWP peer process. The response is then transformed to HTTP Response and sent back directly to the web client (browser).
|
Requirements:
Installation:
GlassFish Installation and Configuration
http port of GlassFish is 1080 during the server setup.LRWP agent Installation
LRWPAgent_bin.tar.gz (LRWP agent binaries) files in your directory ($HOME_DIR directory).2.1. Open the admin console of the Sun Web Application Server.
2.2. Give path toLRWPAgent.warfile for deployment($HOME_DIR/LRWPAgent/dist/LRWPAgent.war).
2.3. Deploy the war file on the root context of GlassFish. This can be done during the deployment of the war file.
LRWP agent Configuration
The user can configure/tune different parameters of the LRWP agent module. All parameters are defined in the 'web.xml' file included in the distribution. The parameter names and their functions are described here:
numAgents is '2', and starting port is defined as '1081', then two instances of the LRWP agent would run, the first instance bound to port 1081 and second instance bound to port 1082. The parameter name in the configuration file (web.xml) is "startPort". The LRWP peer is a client which connects to the LRWP agent running on the GlassFish application server . A sample program is available on the Xitami site. The program can be compiled and the resultant binary can serve as the basic testing tool for a LRWP agent on GlassFish.
The program can be compiled from command line and the SFL library from Imatix Inc. needs to be included as the library at the command line.
Before compiling the example code, change the arguments in the lrwp_connect() function. For example, localhost and the port number can be replaced with the hostname of the LRWP agent machine and the port number on which the LRWP agent is running.
lrwp_connect(&lrwp, "hello", "localhost", "81", ""); |
The standard command line for compilation can be like :
%cc -I<path to the SMT library> -I<Path to the SFL Library> lrwp_peer.c \
-llrwp_context -lsfl-32b-lrwp -lsfl-32b -lsmt-32b -lsocket -lnsl -o lrwp_peerlrwp_peer
|
Once compiled, the binary can be tested against an LRWP agent. The below mentioned steps can prove the basic functionality of the LRWP agent:
http://localhost:1080, appended with hello as the context.A more thorough and better testing can be done using a Java programming language implementation of the LRWP peer called Sokrates [Available at http://www.dreamlandbbs.com/files/gfd/appjava/sokr_v17.zip ].
Sokrates Installation and Startup
sokr_v17.zip% cd $HOME_DIR/Sokrates% cd $HOME_DIR/Sokrates% java net.conacom.servletrunner.main.Runnerhttp://localhost:1080/demoThis will launch the Sokrates default page. You can then run the different operations listed on this page.
The following set of operations can be tested on LRWP agent using the Sokrates servlet runner.
The above listed operations are the standard test of a fully functional LRWP agent and failure of any of these operations shows a non-implementation of the functionality in the agent.
The LRWP agent in Java with GlassFish works well and works with different language-based LRWP peers. It has been tested with C, C++ and Java programming language-based LRWP peers. The performance of the LRWP agent is very good and in fact exceeds Xitami's implementation on a 4 core x86 system. The LRWP agent implementation will also be made available as open source on java.net.
We would like to thank Satyajit Tripathi for excellent project management, managing resources efficiently across time zones with time lines, making communication very efficient and Bruce Chapman for reviewing and providing some fine suggestions making the paper easier to read.