Hi all.
I am fairly new to Jetty as well as the Jetty mailing lists so please
correct me if this message is unsuitable for this list.

I am currently using Jetty 8.1.7 and was wondering if it would be possible
to modify the read timeout for a HttpClient while the client is running and
serving requests.
Currently it only seems to be possible to change the read timeout by
calling setTimeout() and then start() on the client.

I have created a simple example client which highlights the issue and I
will post the code below.
I pointed the client at a socket server which accepts the connection but
never replies in order to trigger a timeout.
The latency is always around 2500ms so it seems the client is still using
the code from the the first point I set the timeout but ignores the second.
I also noticed the client seems to use the default timeout and waits 32
seconds if I don't call setTimeout() until after calling start().

here's the code for the client:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jettytest;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.util.thread.QueuedThreadPool;

/**
 *
 * @author tony.lowry
 */
public class JettyTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        String host;
        if(args.length < 1 || args[0] == null)
        {

            host = "127.0.0.1";
            Logger.getLogger(JettyTest.class.getName()).log(Level.INFO, "No
host supplied, using : " + host);
        }
        else
        {
            host = args[0];
        }

        String port;
        if(args.length < 2 || args[1] == null)
        {
            port = "8809";
            Logger.getLogger(JettyTest.class.getName()).log(Level.INFO, "No
port supplied, using : " + port);
        }
        else
        {
            port = args[1];
        }

        //Set up the HttpClient and thread pool
        HttpClient client = new HttpClient();
        client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
        client.setMaxConnectionsPerAddress(200); // max 200 concurrent
connections to every address
        client.setThreadPool(new QueuedThreadPool(250)); // max 250 threads

        //Set the timeout before starting the Httpclient, delete this and
the client will wait 32 seconds
        client.setTimeout(2500);
        client.start();

        //This timeout won't have any effect as the client has been started
        client.setTimeout(4400);
        String url = "http://"+host+":"+port;

        Logger.getLogger(JettyTest.class.getName()).log(Level.INFO,
"Sending request to " + url);
        sendRequest(client, url);
        client.destroy();
        Logger.getLogger(JettyTest.class.getName()).log(Level.INFO,
"JettyTest all done, returning");
        System.exit(0);
    }


    public static void sendRequest(HttpClient client, String targetURL) {
        ContentExchange exchange = new ContentExchange(true);
        exchange.setURL(targetURL);

        //Record the time before sending the request
        long requestStart = System.currentTimeMillis();
        try {

            //Do a synchronous request
            client.send(exchange);
            int exchangeState = exchange.waitForDone();

            //And record the latency before taking an action
            long requestLatency = System.currentTimeMillis() - requestStart;

            if (exchangeState == HttpExchange.STATUS_COMPLETED) {
                onSuccess(1, requestLatency);
            } else if (exchangeState == HttpExchange.STATUS_EXCEPTED) {
                onError(1, requestLatency);
            } else if (exchangeState == HttpExchange.STATUS_EXPIRED) {
                onExpired(1, requestLatency);
            }
        } catch (Exception ex) {
            Logger.getLogger(JettyTest.class.getName()).log(Level.SEVERE,
null, ex);
            long requestEnd = System.currentTimeMillis() - requestStart;
            onFail(1, requestEnd, ex);
        }
    }

    public static void onSuccess(long requestNum, long latency) {
        Logger.getLogger(JettyTest.class.getName()).log(Level.INFO,
"Request Number " + requestNum + " Succeeded " + " latency: " + latency);
    }

    public static void onError(long requestNum, long latency) {
        Logger.getLogger(JettyTest.class.getName()).log(Level.INFO,
"Request Number " + requestNum + " Error " + " latency: " + latency);
    }

    public static void onExpired(long requestNum, long latency) {
        Logger.getLogger(JettyTest.class.getName()).log(Level.INFO,
"Request Number " + requestNum + " Expired " + " latency: " + latency);
    }

    public static void onFail(long requestNum, long latency, Exception ex) {
        Logger.getLogger(JettyTest.class.getName()).log(Level.INFO,
"Request Number " + requestNum + " Failed " + " latency: " + latency);
    }
}

Running the client against a socket server which never replies yields this
output:

05-Dec-2012 13:02:18 jettytest.JettyTest main
INFO: Sending request to http://127.0.0.1:8809
2012-12-05 13:02:20.645:WARN:oejc.HttpExchange:EXPIRED
ContentExchange@1ded0fd=G
ET//127.0.0.1:8809/#WAITING(2407ms)->EXPIRED(0ms)sent=2426ms
05-Dec-2012 13:02:20 jettytest.JettyTest onExpired
INFO: Request Number 1 Expired * latency: 2521*
05-Dec-2012 13:02:20 jettytest.JettyTest main
INFO: JettyTest all done, returning

I can attach full sources and build and run scripts for both the Socket
Server and Jetty Client if needed.

Based on the source for the HttpClient it seems the timeout attribute is
set correctly but this attribute is normally only passed on to the timeoutQ
attribute at line 410 in the doStart() method:
_timeoutQ.setDuration(_timeout);

but timeoutQ is not touched in the setTimeout() Method:

    /* ------------------------------------------------------------ */
    /**
     * @param timeout the period in ms that an exchange will wait for a
response from the server.
     */
    public void setTimeout(long timeout)
    {
        _timeout = timeout;
    }

Would it be possible to have the timeout updated while the client is
running as a feature or might there be another way of configuring this type
of read timeout.

Thanks for reading,
Tony Lowry.
_______________________________________________
jetty-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/jetty-users

Reply via email to