Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[jetty-users] Modifying Jetty HttpClient Timeout after HttpClient has been started

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 = "">

        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.




Back to the top