Skip to content

Commit d976868

Browse files
Merge branch 'main' into sanchit/catch-cleanup-exception
2 parents ec4207a + 56eadf3 commit d976868

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

org-code-javabuilder/lib/src/main/java/org/code/javabuilder/LambdaRequestHandler.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.amazonaws.services.apigatewaymanagementapi.AmazonApiGatewayManagementApi;
99
import com.amazonaws.services.apigatewaymanagementapi.AmazonApiGatewayManagementApiClientBuilder;
1010
import com.amazonaws.services.apigatewaymanagementapi.model.DeleteConnectionRequest;
11+
import com.amazonaws.services.apigatewaymanagementapi.model.GetConnectionRequest;
1112
import com.amazonaws.services.apigatewaymanagementapi.model.GoneException;
1213
import com.amazonaws.services.lambda.runtime.Context;
1314
import com.amazonaws.services.lambda.runtime.RequestHandler;
@@ -49,24 +50,27 @@ public class LambdaRequestHandler implements RequestHandler<Map<String, String>,
4950

5051
// Creating these clients here rather than in the request handler method allows us to use
5152
// provisioned concurrency to decrease cold boot time by 3-10 seconds, depending on the lambda
52-
private static final AmazonApiGatewayManagementApi API_CLIENT =
53-
AmazonApiGatewayManagementApiClientBuilder.standard()
54-
.withEndpointConfiguration(
55-
new AwsClientBuilder.EndpointConfiguration(API_ENDPOINT, "us-east-1"))
56-
.build();
5753
private static final AmazonSQS SQS_CLIENT = AmazonSQSClientBuilder.defaultClient();
5854
private static final AmazonS3 S3_CLIENT = AmazonS3ClientBuilder.standard().build();
5955

6056
// Controls whether the current invocation session has been initialized. This should be reset on
6157
// every invocation.
6258
private boolean isSessionInitialized = false;
59+
// API Gateway Client. We create this in the constructor so we can recreate it if it goes away for
60+
// some reason.
61+
private AmazonApiGatewayManagementApi apiClient;
6362

6463
public LambdaRequestHandler() {
6564
// create CachedResources once for the entire container.
6665
// This will only be called once in the initial creation of the lambda instance.
6766
// Documentation: https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html
6867
CachedResources.create();
6968
COLD_BOOT_END = Clock.systemUTC().instant();
69+
this.apiClient =
70+
AmazonApiGatewayManagementApiClientBuilder.standard()
71+
.withEndpointConfiguration(
72+
new AwsClientBuilder.EndpointConfiguration(API_ENDPOINT, "us-east-1"))
73+
.build();
7074
}
7175

7276
/**
@@ -134,7 +138,7 @@ public String handleRequest(Map<String, String> lambdaInput, Context context) {
134138
}
135139

136140
final ExceptionHandler exceptionHandler =
137-
new ExceptionHandler(outputAdapter, new AWSSystemExitHelper(connectionId, API_CLIENT));
141+
new ExceptionHandler(outputAdapter, new AWSSystemExitHelper(connectionId, this.apiClient));
138142
final TempDirectoryManager tempDirectoryManager = new AWSTempDirectoryManager();
139143

140144
CodeExecutionManager codeExecutionManager = null;
@@ -150,7 +154,7 @@ public String handleRequest(Map<String, String> lambdaInput, Context context) {
150154
// Create and start thread that that will notify us if we're nearing the timeout limit
151155
timeoutNotifierThread =
152156
this.createTimeoutThread(
153-
context, outputAdapter, codeExecutionManager, connectionId, API_CLIENT);
157+
context, outputAdapter, codeExecutionManager, connectionId, this.apiClient);
154158
timeoutNotifierThread.start();
155159

156160
// Initialize and start code execution
@@ -162,7 +166,7 @@ public String handleRequest(Map<String, String> lambdaInput, Context context) {
162166
if (timeoutNotifierThread != null) {
163167
timeoutNotifierThread.interrupt();
164168
}
165-
this.shutDown(codeExecutionManager, connectionId, API_CLIENT);
169+
this.shutDown(codeExecutionManager, connectionId, this.apiClient);
166170
}
167171

168172
return "done";
@@ -188,6 +192,8 @@ private void initialize(Map<String, String> lambdaInput, String connectionId, Co
188192
// /opt is the folder all layer files go into.
189193
props.put("sun.awt.fontconfig", "/opt/fontconfig.properties");
190194

195+
this.verifyApiClient(connectionId);
196+
191197
this.isSessionInitialized = true;
192198
}
193199

@@ -214,7 +220,7 @@ private OutputAdapter createOutputAdapter(Map<String, String> lambdaInput)
214220
if (connectionId == null) {
215221
throw new InternalFacingException(INVALID_INPUT, new Exception("Missing connection ID"));
216222
}
217-
final AWSOutputAdapter awsOutputAdapter = new AWSOutputAdapter(connectionId, API_CLIENT);
223+
final AWSOutputAdapter awsOutputAdapter = new AWSOutputAdapter(connectionId, this.apiClient);
218224

219225
try {
220226
final ExecutionType executionType = ExecutionType.valueOf(lambdaInput.get("executionType"));
@@ -270,7 +276,7 @@ private CodeExecutionManager createExecutionManager(
270276
compileList,
271277
tempDirectoryManager,
272278
contentManager,
273-
new AWSSystemExitHelper(connectionId, API_CLIENT));
279+
new AWSSystemExitHelper(connectionId, this.apiClient));
274280
}
275281

276282
/**
@@ -376,4 +382,23 @@ private void cleanUpAWSResources(String connectionId, AmazonApiGatewayManagement
376382
Logger.getLogger(MAIN_LOGGER).removeHandler(allHandlers[i]);
377383
}
378384
}
385+
386+
private void verifyApiClient(String connectionId) {
387+
GetConnectionRequest connectionRequest =
388+
new GetConnectionRequest().withConnectionId(connectionId);
389+
try {
390+
this.apiClient.getConnection(connectionRequest);
391+
} catch (IllegalStateException e) {
392+
// This can occur if the api client has been shut down, which we have seen happen on occasion.
393+
// Recreate the api client in this case. Log a warning so we can track when this happens.
394+
Logger.getLogger(MAIN_LOGGER)
395+
.warning(
396+
"Received illegal state exception when trying to talk to API Gateway. Recreating api client.");
397+
this.apiClient =
398+
AmazonApiGatewayManagementApiClientBuilder.standard()
399+
.withEndpointConfiguration(
400+
new AwsClientBuilder.EndpointConfiguration(API_ENDPOINT, "us-east-1"))
401+
.build();
402+
}
403+
}
379404
}

0 commit comments

Comments
 (0)