Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to increase ReadTimeout in Google HTTP Client

I have my application running in GAE. This application makes REST call to my CloudML.

Here is the code for that

GoogleCredential credential = GoogleCredential.getApplicationDefault()
        .createScoped(Collections.singleton(CLOUDML_SCOPE));
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
HttpRequestFactory requestFactory = httpTransport.createRequestFactory(
        credential);
GenericUrl url = new GenericUrl(cloudMLRestUrl);

JacksonFactory jacksonFactory = new JacksonFactory();
JsonHttpContent jsonHttpContent = new JsonHttpContent(jacksonFactory, getPayLoad());

ByteArrayOutputStream baos = new ByteArrayOutputStream();

jsonHttpContent.setWrapperKey("instances");
jsonHttpContent.writeTo(baos);
LOG.info("Executing request... " + baos.toString());
HttpRequest request = requestFactory.buildPostRequest(url, jsonHttpContent);

HttpResponse response = request.execute();  

Often the above code results in ReadTimeout exception.

java.net.SocketTimeoutException: Read timed out at 
java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.8.0_121] at 
java.net.SocketInputStream.socketRead(SocketInputStream.java:116) 
~[na:1.8.0_121] at 
java.net.SocketInputStream.read(SocketInputStream.java:171) ~[na:1.8.0_121] 
at 

It seems we can add HttpRequestInitializer with custom timeout, but we need to pass GoogleCredential while create HttpRequestFactory HttpRequestFactory requestFactory = httpTransport.createRequestFactory(GoogleCredential);

Hence I can't use custom HTTPRequestInitializer. How can I increase the readTimeout for HttpRequestFactory created using GoogleCredential HTTPRequestInitializer?

like image 758
sag Avatar asked May 03 '17 09:05

sag


Video Answer


1 Answers

I haven't tried this, but I'd expect you to be able to effectively chain the request initializers together:

final GoogleCredential credential = ...;
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
HttpRequestFactory requestFactory = httpTransport.createRequestFactory(
    new HttpRequestInitializer() {
        @Override public void initialize(HttpRequest request) {
            credential.initialize(request);
            request.setReadTimeout(...);
        }
    });

Or as a lambda expression:

final GoogleCredential credential = ...;
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
HttpRequestFactory requestFactory = httpTransport.createRequestFactory(
    request -> {
        credential.initialize(request);
        request.setReadTimeout(...);
    });

In other words, when a new request is created, the credential is able to set headers etc, and then you set the read timeout as well.

like image 51
Jon Skeet Avatar answered Oct 17 '22 01:10

Jon Skeet