3
votes

I need to invoke a lambda function once (with no retry). That lambda take up to 5/10 minutes to execute.

I found multiple posts about timeouts and tried each one without success

try {
    InvokeRequest invokeRequest = new InvokeRequest()
        .withFunctionName("mylambdaname")
        .withPayload(objectMapper.writeValueAsString(payload));

    //invokeRequest.setSdkRequestTimeout(0);
    //invokeRequest.setSdkClientExecutionTimeout(0);
    //invokeRequest.withSdkRequestTimeout(0);
    //invokeRequest.withSdkClientExecutionTimeout(0);

    AWSLambda awsLambda = AWSLambdaClientBuilder.standard()
        .withCredentials(new EC2ContainerCredentialsProviderWrapper())
        .withRegion(Regions.EU_WEST_1)
        .withClientConfiguration(new ClientConfiguration()
            //.withConnectionTimeout(0)
            //.withRequestTimeout(0)
            //.withClientExecutionTimeout(0)
            //.withSocketTimeout(0)
            .withMaxErrorRetry(0)
        ).build();

    awsLambda.invoke(invokeRequest);
} catch (ServiceException | JsonProcessingException e) {
    LOGGER.error(e.getMessage());
}

Setting up timeouts (like 15*60*1000) or none (0) still triggers a ReadTimeout after exactly one minute. I also tried to install SDK v2 from AWS and the same problem shows up.

Tried examples :

PS: The lambda does work if the long task is shorten, so it's all about timeouts here

Full stacktrace

java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:457) at sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68) at sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1095) at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:72) at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:815) at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137) at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153) at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157) at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) at com.amazonaws.http.protocol.SdkHttpRequestExecutor.doReceiveResponse(SdkHttpRequestExecutor.java:82) at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) at com.amazonaws.http.apache.client.impl.SdkHttpClient.execute(SdkHttpClient.java:72) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1074) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:745) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:719) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:701) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:669) at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:651) at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:515) at com.amazonaws.services.lambda.AWSLambdaClient.doInvoke(AWSLambdaClient.java:2682) at com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:2651) at com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:2640) at com.amazonaws.services.lambda.AWSLambdaClient.executeInvoke(AWSLambdaClient.java:1503) at com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:1474)
at Repository.invokeLambda(Repository.java:60)
at Service.invoke(Service.java:40)
at Controller.invoke(Controller.java:37)
at Controller$$FastClassBySpringCGLIB$$9d602606.invoke()

2
Do you have the full stack trace?matt freake
@mattfreake provided it :)IQbrod
Setting SocketTimeout at 0 does not leave a stacktrace, the lambda fails without expected logs after exactly one minute (timeout), but doesn't throw such ExceptionIQbrod
Can you share the exact version of Spring Boot, AWS SDK. I tried with aws-sdk 1.11.1010 and spring boot 2.4.5 and spring cloud Hoxton.SR11 worked fine with a function taking 14 minutes of time. If you could create a git repo, that would be great.GSSwain
Agree - if you create a GIT instance. the community can def help you trouble shoot better. My recommendation here is to stop using Java V1 and move to V2. (using V2 is much better practice)smac2020

2 Answers

0
votes

These methods should do the trick which I saw that you have commented out:

  • setSDKRequestTimeout(int milliseconds)
  • setSdkClientExecutionTimeout(int milliseconds)

I don't think you're supposed to use 0. You should use 15*60*1000

https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/AmazonWebServiceRequest.html#setSdkRequestTimeout-int-

0
votes

This is worked for me, the timeout value set to 15 minutes:

AWSLambdaClientBuilder.standard().withClientConfiguration(new ClientConfiguration().withSocketTimeout(900000)) 

can you check the default lambda timeout value on AWS? AWS -> Lambda -> your function -> Change the Timeout setting.

enter image description here