Skip to content

Commit 0179bd1

Browse files
committed
Added variable to disable timer. Added timer call to all important actions. Added Timer enabled to all samples. Removed POJO handler from samples since we recommend the stream handler
1 parent 22ef1d6 commit 0179bd1

File tree

20 files changed

+125
-200
lines changed

20 files changed

+125
-200
lines changed

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletRequest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler;
1717
import com.amazonaws.serverless.proxy.internal.SecurityUtils;
18+
import com.amazonaws.serverless.proxy.internal.testutils.Timer;
1819
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
1920
import com.amazonaws.serverless.proxy.model.ContainerConfig;
2021
import com.amazonaws.services.lambda.runtime.Context;
@@ -663,7 +664,7 @@ private Map<String, Part> getMultipartFormParametersMap() {
663664
if (!ServletFileUpload.isMultipartContent(this)) { // isMultipartContent also checks the content type
664665
return new HashMap<>();
665666
}
666-
667+
Timer.start("SERVLET_REQUEST_GET_MULTIPART_PARAMS");
667668
Map<String, Part> output = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
668669

669670
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
@@ -689,8 +690,10 @@ private Map<String, Part> getMultipartFormParametersMap() {
689690
output.put(item.getFieldName(), newPart);
690691
}
691692
} catch (FileUploadException e) {
693+
Timer.stop("SERVLET_REQUEST_GET_MULTIPART_PARAMS");
692694
log.error("Could not read multipart upload file", e);
693695
}
696+
Timer.stop("SERVLET_REQUEST_GET_MULTIPART_PARAMS");
694697
return output;
695698
}
696699

@@ -720,7 +723,7 @@ private Map<String, List<String>> getFormUrlEncodedParametersMap() {
720723
if (!contentType.startsWith(MediaType.APPLICATION_FORM_URLENCODED) || !getMethod().toLowerCase(Locale.ENGLISH).equals("post")) {
721724
return new HashMap<>();
722725
}
723-
726+
Timer.start("SERVLET_REQUEST_GET_FORM_PARAMS");
724727
String rawBodyContent = request.getBody();
725728

726729
Map<String, List<String>> output = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@@ -736,7 +739,7 @@ private Map<String, List<String>> getFormUrlEncodedParametersMap() {
736739
values.add(decodeValueIfEncoded(parameterKeyValue[1]));
737740
output.put(decodeValueIfEncoded(parameterKeyValue[0]), values);
738741
}
739-
742+
Timer.stop("SERVLET_REQUEST_GET_FORM_PARAMS");
740743
return output;
741744
}
742745

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletResponseWriter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.amazonaws.serverless.exceptions.InvalidResponseObjectException;
1717
import com.amazonaws.serverless.proxy.ResponseWriter;
18+
import com.amazonaws.serverless.proxy.internal.testutils.Timer;
1819
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
1920
import com.amazonaws.services.lambda.runtime.Context;
2021

@@ -33,6 +34,7 @@ public class AwsProxyHttpServletResponseWriter extends ResponseWriter<AwsHttpSer
3334
@Override
3435
public AwsProxyResponse writeResponse(AwsHttpServletResponse containerResponse, Context lambdaContext)
3536
throws InvalidResponseObjectException {
37+
Timer.start("SERVLET_RESPONSE_WRITE");
3638
AwsProxyResponse awsProxyResponse = new AwsProxyResponse();
3739
if (containerResponse.getAwsResponseBodyString() != null) {
3840
String responseString;
@@ -53,7 +55,7 @@ public AwsProxyResponse writeResponse(AwsHttpServletResponse containerResponse,
5355
} else {
5456
awsProxyResponse.setStatusCode(containerResponse.getStatus());
5557
}
56-
58+
Timer.stop("SERVLET_RESPONSE_WRITE");
5759
return awsProxyResponse;
5860
}
5961
}

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/testutils/Timer.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,21 @@
77

88
public final class Timer {
99
private volatile static Map<String, TimerInfo> timers = new LinkedHashMap<>();
10+
private volatile static boolean enabled = false;
1011

1112
public static void start(String timerName) {
13+
if (!enabled) {
14+
return;
15+
}
16+
1217
timers.put(timerName, new TimerInfo(System.currentTimeMillis()));
1318
}
1419

1520
public static long stop(String timerName) {
21+
if (!enabled) {
22+
return 0L;
23+
}
24+
1625
TimerInfo info = timers.get(timerName);
1726
if (info == null) {
1827
throw new IllegalArgumentException("Could not find timer " + timerName);
@@ -33,6 +42,14 @@ public static TimerInfo getTimer(String timerName) {
3342
return timers.get(timerName);
3443
}
3544

45+
public static void enable() {
46+
enabled = true;
47+
}
48+
49+
public static void disable() {
50+
enabled = false;
51+
}
52+
3653
private static class TimerInfo {
3754
private long startTime;
3855
private long stopTime;

aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyHandlerFilter.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,17 @@ public class JerseyHandlerFilter implements Filter, Container {
4848
private Application app;
4949
private Logger log = LoggerFactory.getLogger(JerseyHandlerFilter.class);
5050

51-
public JerseyHandlerFilter(Application jaxApplication) {
52-
Timer.start("JERSEY_FILTER_INIT");
51+
JerseyHandlerFilter(Application jaxApplication) {
52+
Timer.start("JERSEY_FILTER_CONSTRUCTOR");
5353
app = jaxApplication;
5454

5555
jersey = new ApplicationHandler(app);
5656
jersey.onStartup(this);
57-
Timer.stop("JERSEY_FILTER_INIT");
57+
Timer.stop("JERSEY_FILTER_CONSTRUCTOR");
5858
}
5959

6060
@Override
61-
public void init(FilterConfig filterConfig)
62-
throws ServletException {
61+
public void init(FilterConfig filterConfig) {
6362
log.info("Initialize Jersey application handler");
6463
}
6564

@@ -97,6 +96,7 @@ public void destroy() {
9796
// servlet implementation
9897
@SuppressFBWarnings({ "SERVLET_HEADER", "SERVLET_QUERY_STRING" })
9998
private ContainerRequest servletRequestToContainerRequest(ServletRequest request) {
99+
Timer.start("JERSEY_SERVLET_REQUEST_TO_CONTAINER");
100100
URI basePathUri;
101101
URI requestPathUri;
102102
String basePath = "/";
@@ -131,7 +131,7 @@ private ContainerRequest servletRequestToContainerRequest(ServletRequest request
131131
(SecurityContext)servletRequest.getAttribute(JAX_SECURITY_CONTEXT_PROPERTY),
132132
apiGatewayProperties);
133133

134-
InputStream requestInputStream = null;
134+
InputStream requestInputStream;
135135
try {
136136
requestInputStream = servletRequest.getInputStream();
137137
if (requestInputStream != null) {
@@ -147,7 +147,7 @@ private ContainerRequest servletRequestToContainerRequest(ServletRequest request
147147
String headerKey = headerNames.nextElement();
148148
requestContext.header(headerKey, servletRequest.getHeader(headerKey));
149149
}
150-
150+
Timer.stop("JERSEY_SERVLET_REQUEST_TO_CONTAINER");
151151
return requestContext;
152152
}
153153

@@ -175,12 +175,14 @@ public ApplicationHandler getApplicationHandler() {
175175
*/
176176
@Override
177177
public void reload() {
178+
Timer.start("JERSEY_RELOAD_DEFAULT");
178179
jersey.onShutdown(this);
179180

180181
jersey = new ApplicationHandler(app);
181182

182183
jersey.onReload(this);
183184
jersey.onStartup(this);
185+
Timer.stop("JERSEY_RELOAD_DEFAULT");
184186
}
185187

186188

@@ -191,12 +193,14 @@ public void reload() {
191193
*/
192194
@Override
193195
public void reload(ResourceConfig resourceConfig) {
196+
Timer.start("JERSEY_RELOAD_CONFIG");
194197
jersey.onShutdown(this);
195198

196199
app = resourceConfig;
197200
jersey = new ApplicationHandler(resourceConfig);
198201

199202
jersey.onReload(this);
200203
jersey.onStartup(this);
204+
Timer.stop("JERSEY_RELOAD_CONFIG");
201205
}
202206
}

aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyLambdaContainerHandler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ public JerseyLambdaContainerHandler(RequestReader<RequestType, AwsProxyHttpServl
123123
Application jaxRsApplication) {
124124

125125
super(requestReader, responseWriter, securityContextWriter, exceptionHandler);
126-
Timer.start("JERSEY_START_TIMER");
126+
Timer.start("JERSEY_CONTAINER_CONSTRUCTOR");
127127
this.jaxRsApplication = jaxRsApplication;
128128
this.initialized = false;
129129
this.jerseyFilter = new JerseyHandlerFilter(this.jaxRsApplication);
130-
Timer.stop("JERSEY_START_TIMER");
130+
Timer.stop("JERSEY_CONTAINER_CONSTRUCTOR");
131131
}
132132

133133
//-------------------------------------------------------------
@@ -148,7 +148,7 @@ protected void handleRequest(AwsProxyHttpServletRequest httpServletRequest, AwsH
148148
super.handleRequest(httpServletRequest, httpServletResponse, lambdaContext);
149149

150150
if (!initialized) {
151-
Timer.start("JERSEY_INITIALIZATION");
151+
Timer.start("JERSEY_COLD_START_INIT");
152152
// call the onStartup event if set to give developers a chance to set filters in the context
153153
if (startupHandler != null) {
154154
startupHandler.onStartup(getServletContext());
@@ -159,7 +159,7 @@ protected void handleRequest(AwsProxyHttpServletRequest httpServletRequest, AwsH
159159
jerseyFilterReg.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
160160

161161
initialized = true;
162-
Timer.stop("JERSEY_INITIALIZATION");
162+
Timer.stop("JERSEY_COLD_START_INIT");
163163
}
164164

165165
httpServletRequest.setServletContext(getServletContext());

aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyServletResponseWriter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515

1616
import com.amazonaws.serverless.proxy.internal.SecurityUtils;
17+
import com.amazonaws.serverless.proxy.internal.testutils.Timer;
1718

1819
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
1920
import org.glassfish.jersey.server.ContainerException;
@@ -78,18 +79,22 @@ public JerseyServletResponseWriter(ServletResponse resp, CountDownLatch latch) {
7879
@SuppressFBWarnings("HTTP_RESPONSE_SPLITTING") // suppress this because headers are sanitized in the setHeader method of the servlet response
7980
public OutputStream writeResponseStatusAndHeaders(long contentLength, ContainerResponse containerResponse)
8081
throws ContainerException {
82+
Timer.start("JERSEY_WRITE_RESPONSE");
8183
servletResponse.setStatus(containerResponse.getStatusInfo().getStatusCode());
8284
for (final Map.Entry<String, List<String>> e : containerResponse.getStringHeaders().entrySet()) {
8385
for (final String value : e.getValue()) {
8486
servletResponse.setHeader(e.getKey(), value);
8587
}
8688
}
8789
try {
90+
Timer.stop("JERSEY_WRITE_RESPONSE");
8891
return servletResponse.getOutputStream();
8992
} catch (IOException e) {
9093
log.error("Could not get servlet response output stream", e);
94+
Timer.stop("JERSEY_WRITE_RESPONSE");
9195
throw new InternalServerErrorException("Could not get servlet response output stream", e);
9296
}
97+
9398
}
9499

95100

aws-serverless-java-container-spark/src/main/java/com/amazonaws/serverless/proxy/spark/SparkLambdaContainerHandler.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.amazonaws.serverless.proxy.RequestReader;
2121
import com.amazonaws.serverless.proxy.ResponseWriter;
2222
import com.amazonaws.serverless.proxy.SecurityContextWriter;
23+
import com.amazonaws.serverless.proxy.internal.testutils.Timer;
2324
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
2425
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
2526
import com.amazonaws.serverless.proxy.internal.servlet.*;
@@ -32,7 +33,6 @@
3233
import org.slf4j.LoggerFactory;
3334
import spark.Service;
3435
import spark.Spark;
35-
import spark.embeddedserver.EmbeddedServerFactory;
3636
import spark.embeddedserver.EmbeddedServers;
3737

3838
import javax.servlet.DispatcherType;
@@ -42,7 +42,6 @@
4242
import java.lang.reflect.InvocationTargetException;
4343
import java.lang.reflect.Method;
4444
import java.security.AccessController;
45-
import java.security.PrivilegedAction;
4645
import java.security.PrivilegedActionException;
4746
import java.security.PrivilegedExceptionAction;
4847
import java.util.EnumSet;
@@ -126,6 +125,7 @@ public SparkLambdaContainerHandler(RequestReader<RequestType, AwsProxyHttpServle
126125
LambdaEmbeddedServerFactory embeddedServerFactory)
127126
throws ContainerInitializationException {
128127
super(requestReader, responseWriter, securityContextWriter, exceptionHandler);
128+
Timer.start("SPARK_CONTAINER_HANDLER_CONSTRUCTOR");
129129

130130
EmbeddedServers.add(LAMBDA_EMBEDDED_SERVER_CODE, embeddedServerFactory);
131131
this.lambdaServerFactory = embeddedServerFactory;
@@ -155,8 +155,10 @@ public SparkLambdaContainerHandler(RequestReader<RequestType, AwsProxyHttpServle
155155
} else {
156156
log.error("Unknown exception while modifying Spark class", e.getException());
157157
}
158+
Timer.stop("SPARK_CONTAINER_HANDLER_CONSTRUCTOR");
158159
throw new ContainerInitializationException("Could not initialize Spark server", e.getException());
159160
}
161+
Timer.stop("SPARK_CONTAINER_HANDLER_CONSTRUCTOR");
160162
}
161163

162164
//-------------------------------------------------------------
@@ -173,11 +175,12 @@ protected AwsHttpServletResponse getContainerResponse(AwsProxyHttpServletRequest
173175
@Override
174176
protected void handleRequest(AwsProxyHttpServletRequest httpServletRequest, AwsHttpServletResponse httpServletResponse, Context lambdaContext)
175177
throws Exception {
176-
178+
Timer.start("SPARK_HANDLE_REQUEST");
177179
// this method of the AwsLambdaServletContainerHandler sets the request context
178180
super.handleRequest(httpServletRequest, httpServletResponse, lambdaContext);
179181

180182
if (embeddedServer == null) {
183+
Timer.start("SPARK_COLD_START");
181184
log.debug("First request, getting new server instance");
182185

183186
// trying to call init in case the embedded server had not been initialized.
@@ -197,10 +200,12 @@ protected void handleRequest(AwsProxyHttpServletRequest httpServletRequest, AwsH
197200
// manually add the spark filter to the chain. This should the last one and match all uris
198201
FilterRegistration.Dynamic sparkRegistration = getServletContext().addFilter("SparkFilter", embeddedServer.getSparkFilter());
199202
sparkRegistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
203+
Timer.stop("SPARK_COLD_START");
200204
}
201205

202206
httpServletRequest.setServletContext(getServletContext());
203207

204208
doFilter(httpServletRequest, httpServletResponse, null);
209+
Timer.stop("SPARK_HANDLE_REQUEST");
205210
}
206211
}

aws-serverless-java-container-spark/src/main/java/com/amazonaws/serverless/proxy/spark/embeddedserver/LambdaEmbeddedServer.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.amazonaws.serverless.proxy.spark.embeddedserver;
22

3+
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
4+
import com.amazonaws.serverless.proxy.internal.testutils.Timer;
5+
36
import org.slf4j.Logger;
47
import org.slf4j.LoggerFactory;
58
import spark.embeddedserver.EmbeddedServer;
@@ -10,10 +13,6 @@
1013
import spark.staticfiles.StaticFilesConfiguration;
1114

1215
import javax.servlet.Filter;
13-
import javax.servlet.ServletException;
14-
import javax.servlet.http.HttpServletRequest;
15-
import javax.servlet.http.HttpServletResponse;
16-
import java.io.IOException;
1716
import java.util.Map;
1817
import java.util.Optional;
1918

@@ -36,12 +35,14 @@ public class LambdaEmbeddedServer
3635
//-------------------------------------------------------------
3736

3837
LambdaEmbeddedServer(Routes routes, StaticFilesConfiguration filesConfig, boolean multipleHandlers) {
38+
Timer.start("SPARK_EMBEDDED_SERVER_CONSTRUCTOR");
3939
applicationRoutes = routes;
4040
staticFilesConfiguration = filesConfig;
4141
hasMultipleHandler = multipleHandlers;
4242

4343
// try to initialize the filter here.
4444
sparkFilter = new MatcherFilter(applicationRoutes, staticFilesConfiguration, true, hasMultipleHandler);
45+
Timer.stop("SPARK_EMBEDDED_SERVER_CONSTRUCTOR");
4546
}
4647

4748

@@ -50,14 +51,15 @@ public class LambdaEmbeddedServer
5051
//-------------------------------------------------------------
5152
@Override
5253
public int ignite(String s, int i, SslStores sslStores, int i1, int i2, int i3)
53-
throws Exception {
54+
throws ContainerInitializationException {
55+
Timer.start("SPARK_EMBEDDED_IGNITE");
5456
log.info("Starting Spark server, ignoring port and host");
5557
// if not initialized yet
5658
if (sparkFilter == null) {
5759
sparkFilter = new MatcherFilter(applicationRoutes, staticFilesConfiguration, true, hasMultipleHandler);
5860
}
5961
sparkFilter.init(null);
60-
62+
Timer.stop("SPARK_EMBEDDED_IGNITE");
6163
return i;
6264
}
6365

@@ -71,8 +73,7 @@ public void configureWebSockets(Map<String, WebSocketHandlerWrapper> webSocketHa
7173

7274

7375
@Override
74-
public void join()
75-
throws InterruptedException {
76+
public void join() {
7677
log.info("Called join method, nothing to do here since Lambda only runs a single event per container");
7778
}
7879

@@ -93,12 +94,6 @@ public int activeThreadCount() {
9394
// Methods - Public
9495
//-------------------------------------------------------------
9596

96-
public void handle(HttpServletRequest request, HttpServletResponse response)
97-
throws IOException, ServletException {
98-
sparkFilter.doFilter(request, response, null);
99-
}
100-
101-
10297
/**
10398
* Returns the initialized instance of the main Spark filter.
10499
* @return The spark filter instance.

0 commit comments

Comments
 (0)