From 17afb9a418f9a66b2a91e3483fa84eed626aaa2f Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Tue, 26 Mar 2024 11:52:47 +0100 Subject: [PATCH 1/3] GH-805 Fix web context initialization during snapstart Also updated to s-c-function-serverless-webb 4.1.1-SNAPSHOT This commit forces wait for full context initialization if context is created during snapstart creation --- aws-serverless-java-container-springboot3/pom.xml | 2 +- .../proxy/spring/SpringDelegatingLambdaContainerHandler.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/aws-serverless-java-container-springboot3/pom.xml b/aws-serverless-java-container-springboot3/pom.xml index 23ceec081..def9c9015 100644 --- a/aws-serverless-java-container-springboot3/pom.xml +++ b/aws-serverless-java-container-springboot3/pom.xml @@ -25,7 +25,7 @@ org.springframework.cloud spring-cloud-function-serverless-web - 4.0.6 + 4.1.1-SNAPSHOT com.amazonaws.serverless diff --git a/aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandler.java b/aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandler.java index f1a3b526e..56ebe8305 100644 --- a/aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandler.java +++ b/aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandler.java @@ -53,6 +53,10 @@ public SpringDelegatingLambdaContainerHandler() { public SpringDelegatingLambdaContainerHandler(Class... startupClasses) { this.startupClasses = startupClasses; this.mvc = ServerlessMVC.INSTANCE(this.startupClasses); + if (System.getenv().containsKey("AWS_LAMBDA_INITIALIZATION_TYPE") + && System.getenv().get("AWS_LAMBDA_INITIALIZATION_TYPE").equals("snap-start")) { + mvc.waitForContext(); + } this.mapper = new ObjectMapper(); this.responseWriter = new AwsProxyHttpServletResponseWriter(); } From 82340e139f6f23cff101960bb462a56ef7bbb036 Mon Sep 17 00:00:00 2001 From: Dennis Kieselhorst Date: Thu, 4 Apr 2024 15:09:35 +0200 Subject: [PATCH 2/3] chore(deps): Update to spring-cloud-function-serverless-web 4.1.1 release --- aws-serverless-java-container-springboot3/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws-serverless-java-container-springboot3/pom.xml b/aws-serverless-java-container-springboot3/pom.xml index def9c9015..50a4f5422 100644 --- a/aws-serverless-java-container-springboot3/pom.xml +++ b/aws-serverless-java-container-springboot3/pom.xml @@ -25,7 +25,7 @@ org.springframework.cloud spring-cloud-function-serverless-web - 4.1.1-SNAPSHOT + 4.1.1 com.amazonaws.serverless From 2d3174cfd300f061f9ddd0b44d317a3d90b7bd93 Mon Sep 17 00:00:00 2001 From: Dennis Kieselhorst Date: Thu, 4 Apr 2024 15:20:48 +0200 Subject: [PATCH 3/3] fix: Reinitialization of Spring context when using SnapStart #805 --- .../proxy/AsyncInitializationWrapper.java | 14 +++----- .../proxy/InitializationTypeHelper.java | 33 +++++++++++++++++++ ...pringDelegatingLambdaContainerHandler.java | 4 +-- 3 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/InitializationTypeHelper.java diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AsyncInitializationWrapper.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AsyncInitializationWrapper.java index 57f4e8a06..12e1590ab 100644 --- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AsyncInitializationWrapper.java +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AsyncInitializationWrapper.java @@ -41,17 +41,13 @@ public class AsyncInitializationWrapper extends InitializationWrapper { private static final int DEFAULT_INIT_GRACE_TIME_MS = 150; private static final String INIT_GRACE_TIME_ENVIRONMENT_VARIABLE_NAME = "AWS_SERVERLESS_JAVA_CONTAINER_INIT_GRACE_TIME"; - private static final String INITIALIZATION_TYPE_ENVIRONMENT_VARIABLE_NAME = "AWS_LAMBDA_INITIALIZATION_TYPE"; - private static final String INITIALIZATION_TYPE_ON_DEMAND = "on-demand"; - private static final String INITIALIZATION_TYPE = System.getenv().getOrDefault(INITIALIZATION_TYPE_ENVIRONMENT_VARIABLE_NAME,INITIALIZATION_TYPE_ON_DEMAND); - private static final boolean ASYNC_INIT_DISABLED = !INITIALIZATION_TYPE.equals(INITIALIZATION_TYPE_ON_DEMAND); private static final int INIT_GRACE_TIME_MS = Integer.parseInt(System.getenv().getOrDefault( INIT_GRACE_TIME_ENVIRONMENT_VARIABLE_NAME, Integer.toString(DEFAULT_INIT_GRACE_TIME_MS))); private static final int LAMBDA_MAX_INIT_TIME_MS = 10_000; private CountDownLatch initializationLatch; private final long actualStartTime; - private Logger log = LoggerFactory.getLogger(AsyncInitializationWrapper.class); + private final Logger log = LoggerFactory.getLogger(AsyncInitializationWrapper.class); /** @@ -73,8 +69,8 @@ public AsyncInitializationWrapper() { @Override public void start(InitializableLambdaContainerHandler handler) throws ContainerInitializationException { - if(ASYNC_INIT_DISABLED){ - log.info("Async init disabled due to \"{}\" initialization", INITIALIZATION_TYPE); + if (InitializationTypeHelper.isAsyncInitializationDisabled()){ + log.info("Async init disabled due to \"{}\" initialization", InitializationTypeHelper.getInitializationType()); super.start(handler); return; } @@ -107,7 +103,7 @@ public long getActualStartTimeMs() { @Override public CountDownLatch getInitializationLatch() { - if (ASYNC_INIT_DISABLED){ + if (InitializationTypeHelper.isAsyncInitializationDisabled()){ return super.getInitializationLatch(); } return initializationLatch; @@ -116,7 +112,7 @@ public CountDownLatch getInitializationLatch() { private static class AsyncInitializer implements Runnable { private final InitializableLambdaContainerHandler handler; private CountDownLatch initLatch; - private Logger log = LoggerFactory.getLogger(AsyncInitializationWrapper.class); + private final Logger log = LoggerFactory.getLogger(AsyncInitializationWrapper.class); AsyncInitializer(CountDownLatch latch, InitializableLambdaContainerHandler h) { initLatch = latch; diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/InitializationTypeHelper.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/InitializationTypeHelper.java new file mode 100644 index 000000000..c40c5ecca --- /dev/null +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/InitializationTypeHelper.java @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazonaws.serverless.proxy; + +/** + * Utility class that helps determine the initialization type + */ +public final class InitializationTypeHelper { + + private static final String INITIALIZATION_TYPE_ENVIRONMENT_VARIABLE_NAME = "AWS_LAMBDA_INITIALIZATION_TYPE"; + private static final String INITIALIZATION_TYPE_ON_DEMAND = "on-demand"; + private static final String INITIALIZATION_TYPE = System.getenv().getOrDefault(INITIALIZATION_TYPE_ENVIRONMENT_VARIABLE_NAME, + INITIALIZATION_TYPE_ON_DEMAND); + private static final boolean ASYNC_INIT_DISABLED = !INITIALIZATION_TYPE.equals(INITIALIZATION_TYPE_ON_DEMAND); + + public static boolean isAsyncInitializationDisabled() { + return ASYNC_INIT_DISABLED; + } + + public static String getInitializationType() { + return INITIALIZATION_TYPE; + } +} diff --git a/aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandler.java b/aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandler.java index 56ebe8305..1af435c0f 100644 --- a/aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandler.java +++ b/aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandler.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.io.OutputStream; +import com.amazonaws.serverless.proxy.InitializationTypeHelper; import com.amazonaws.serverless.proxy.model.AwsProxyResponse; import org.springframework.cloud.function.serverless.web.FunctionClassUtils; import org.springframework.cloud.function.serverless.web.ServerlessMVC; @@ -53,8 +54,7 @@ public SpringDelegatingLambdaContainerHandler() { public SpringDelegatingLambdaContainerHandler(Class... startupClasses) { this.startupClasses = startupClasses; this.mvc = ServerlessMVC.INSTANCE(this.startupClasses); - if (System.getenv().containsKey("AWS_LAMBDA_INITIALIZATION_TYPE") - && System.getenv().get("AWS_LAMBDA_INITIALIZATION_TYPE").equals("snap-start")) { + if (InitializationTypeHelper.isAsyncInitializationDisabled()) { mvc.waitForContext(); } this.mapper = new ObjectMapper();