aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJonatan Kronqvist <jonatan.kronqvist@itmill.com>2012-04-19 06:33:34 +0000
committerJonatan Kronqvist <jonatan.kronqvist@itmill.com>2012-04-19 06:33:34 +0000
commitc558076a1981adabbe99c1ec3dbf869ecb27cace (patch)
tree2859bbc2f3bb030eb08d20a19e9ebd31943551b3 /src
parent5b9baad920779278f9e24f22e45499604ef6f7bf (diff)
downloadvaadin-framework-c558076a1981adabbe99c1ec3dbf869ecb27cace.tar.gz
vaadin-framework-c558076a1981adabbe99c1ec3dbf869ecb27cace.zip
Implemented #8694 - API providing profiling info for TestBench 3.x
svn changeset:23582/svn branch:6.8
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/terminal/gwt/client/ApplicationConnection.java32
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java8
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java6
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java22
-rw-r--r--src/com/vaadin/terminal/gwt/server/RequestTimer.java138
5 files changed, 199 insertions, 7 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index 7a3a28495a..93e2657eb4 100644
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -224,12 +224,22 @@ public class ApplicationConnection {
return ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::hasActiveRequest()()
|| ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::isExecutingDeferredCommands()();
}
+
var vi = ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::getVersionInfo()();
if (vi) {
client.getVersionInfo = function() {
return vi;
}
}
+
+ client.getProfilingData = function() {
+ var pd = [
+ ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::lastProcessingTime,
+ ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::totalProcessingTime
+ ];
+ pd = pd.concat(ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::testBenchServerStatus);
+ return pd;
+ }
client.getElementByPath = function(id) {
return componentLocator.@com.vaadin.terminal.gwt.client.ComponentLocator::getElementByPath(Ljava/lang/String;)(id);
@@ -632,6 +642,13 @@ public class ApplicationConnection {
}
int cssWaits = 0;
+
+ protected int lastProcessingTime;
+
+ protected int totalProcessingTime;
+
+ private ValueMap testBenchServerStatus;
+
static final int MAX_CSS_WAITS = 100;
protected void handleWhenCSSLoaded(final String jsonText,
@@ -952,6 +969,13 @@ public class ApplicationConnection {
json.getValueMap("typeMappings"), widgetSet);
}
+ /*
+ * Hook for TestBench to get details about server status
+ */
+ if (json.containsKey("tbss")) {
+ testBenchServerStatus = json.getValueMap("tbss");
+ }
+
Command c = new Command() {
public void execute() {
VConsole.dirUIDL(json, configuration);
@@ -1129,10 +1153,12 @@ public class ApplicationConnection {
// TODO build profiling for widget impl loading time
- final long prosessingTime = (new Date().getTime())
- - start.getTime();
+ lastProcessingTime = (int) ((new Date().getTime()) - start
+ .getTime());
+ totalProcessingTime += lastProcessingTime;
+
VConsole.log(" Processing time was "
- + String.valueOf(prosessingTime) + "ms for "
+ + String.valueOf(lastProcessingTime) + "ms for "
+ jsonText.length() + " characters of JSON");
VConsole.log("Referenced paintables: "
+ idToPaintableDetail.size());
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
index acae039e8b..a5923cb47f 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
@@ -326,6 +326,11 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
protected void handleRequest(PortletRequest request,
PortletResponse response) throws PortletException, IOException {
+ RequestTimer.RequestWrapper wrappedRequest = new RequestTimer.RequestWrapper(
+ request);
+ RequestTimer requestTimer = RequestTimer.get(wrappedRequest);
+ requestTimer.start(wrappedRequest);
+
RequestType requestType = getRequestType(request);
if (requestType == RequestType.UNKNOWN) {
@@ -490,6 +495,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
request, response);
}
+
+ requestTimer.stop();
+ RequestTimer.set(wrappedRequest, requestTimer);
}
}
}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
index 13082cf1aa..04ea423004 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
@@ -401,6 +401,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
+ RequestTimer.RequestWrapper wrappedRequest = new RequestTimer.RequestWrapper(
+ request);
+ RequestTimer requestTimer = RequestTimer.get(wrappedRequest);
+ requestTimer.start(wrappedRequest);
RequestType requestType = getRequestType(request);
if (!ensureCookiesEnabled(requestType, request, response)) {
@@ -549,6 +553,8 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements
request, response);
}
+ requestTimer.stop();
+ RequestTimer.set(wrappedRequest, requestTimer);
}
}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
index c0654359a1..9a6bccebb8 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
@@ -912,7 +912,7 @@ public abstract class AbstractCommunicationManager implements
repaintAll = true;
}
- writeUidlResponce(callback, repaintAll, outWriter, window,
+ writeUidlResponse(request, callback, repaintAll, outWriter, window,
analyzeLayouts);
}
@@ -922,9 +922,9 @@ public abstract class AbstractCommunicationManager implements
}
- public void writeUidlResponce(Callback callback, boolean repaintAll,
- final PrintWriter outWriter, Window window, boolean analyzeLayouts)
- throws PaintException {
+ public void writeUidlResponse(Request request, Callback callback,
+ boolean repaintAll, final PrintWriter outWriter, Window window,
+ boolean analyzeLayouts) throws PaintException {
outWriter.print("\"changes\":[");
ArrayList<Paintable> paintables = null;
@@ -1205,6 +1205,20 @@ public abstract class AbstractCommunicationManager implements
if (dragAndDropService != null) {
dragAndDropService.printJSONResponse(outWriter);
}
+
+ writePerformanceDataForTestBench(request, outWriter);
+ }
+
+ /**
+ * Adds the performance timing data used by TestBench 3 to the UIDL
+ * response.
+ */
+ private void writePerformanceDataForTestBench(final Request request,
+ final PrintWriter outWriter) {
+ Long totalTime = (Long) request.getAttribute("TOTAL");
+ Long lastRequestTime = (Long) request.getAttribute("LASTREQUEST");
+ outWriter.write(String.format(", \"tbss\":[%d, %d]", totalTime,
+ lastRequestTime));
}
private int getTimeoutInterval() {
diff --git a/src/com/vaadin/terminal/gwt/server/RequestTimer.java b/src/com/vaadin/terminal/gwt/server/RequestTimer.java
new file mode 100644
index 0000000000..3649ed3a80
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/server/RequestTimer.java
@@ -0,0 +1,138 @@
+package com.vaadin.terminal.gwt.server;
+
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletSession;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Times the handling of requests and stores the information as an attribute in
+ * the request. The timing info is later passed on to the client in the UIDL and
+ * the client provides JavaScript API for accessing this data from e.g.
+ * TestBench.
+ *
+ * @author Jonatan Kronqvist / Vaadin Ltd
+ */
+public class RequestTimer {
+ public static final String SESSION_ATTR_ID = "REQUESTTIMER";
+
+ private long requestStartTime = 0;
+ private long totalSessionTime = 0;
+ private long lastRequestTime = -1;
+
+ /**
+ * This class acts as a proxy for setting and getting session and request
+ * attributes on HttpServletRequests and PortletRequests. Using this class
+ * we don't need to duplicate code everywhere.
+ */
+ static class RequestWrapper {
+ private final HttpServletRequest servletRequest;
+ private final PortletRequest portletRequest;
+
+ public RequestWrapper(HttpServletRequest servletRequest) {
+ this.servletRequest = servletRequest;
+ portletRequest = null;
+ }
+
+ public RequestWrapper(PortletRequest portletRequest) {
+ this.portletRequest = portletRequest;
+ servletRequest = null;
+ }
+
+ public void setAttribute(String name, Object value) {
+ if (servletRequest != null) {
+ servletRequest.setAttribute(name, value);
+ } else {
+ portletRequest.setAttribute(name, value);
+ }
+ }
+
+ public void setSessionAttribute(String name, Object value) {
+ if (servletRequest != null) {
+ HttpSession session = servletRequest.getSession();
+ if (session != null) {
+ session.setAttribute(name, value);
+ }
+ } else {
+ PortletSession portletSession = portletRequest
+ .getPortletSession();
+ if (portletSession != null) {
+ portletSession.setAttribute(name, value);
+ }
+ }
+ }
+
+ public Object getSessionAttribute(String name) {
+ if (servletRequest != null) {
+ HttpSession session = servletRequest.getSession();
+ if (session != null) {
+ return session.getAttribute(name);
+ }
+ } else {
+ PortletSession portletSession = portletRequest
+ .getPortletSession();
+ if (portletSession != null) {
+ return portletSession.getAttribute(name);
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Starts the timing of a request. This should be called before any
+ * processing of the request.
+ *
+ * @param request
+ * the request.
+ */
+ public void start(RequestWrapper request) {
+ requestStartTime = System.nanoTime();
+ request.setAttribute("TOTAL", totalSessionTime);
+ request.setAttribute("LASTREQUEST", lastRequestTime);
+ }
+
+ /**
+ * Stops the timing of a request. This should be called when all processing
+ * of a request has finished.
+ */
+ public void stop() {
+ // Measure and store the total handling time. This data can be
+ // used in TestBench 3 tests.
+ long time = (System.nanoTime() - requestStartTime) / 1000000;
+ lastRequestTime = time;
+ totalSessionTime += time;
+ }
+
+ /**
+ * Returns a valid request timer for the specified request. Timers are
+ * session bound.
+ *
+ * @param request
+ * the request for which to get a valid timer.
+ * @return a valid timer.
+ */
+ public static RequestTimer get(RequestWrapper request) {
+ RequestTimer timer = (RequestTimer) request
+ .getSessionAttribute(SESSION_ATTR_ID);
+ if (timer == null) {
+ timer = new RequestTimer();
+ }
+ return timer;
+ }
+
+ /**
+ * Associates the specified request timer with the specified request. Since
+ * {@link #get(RequestWrapper)} will, at one point or another, return a new
+ * instance, this method should be called to keep the request <-> timer
+ * association updated.
+ *
+ * @param request
+ * the request for which to set the timer.
+ * @param requestTimer
+ * the timer.
+ */
+ public static void set(RequestWrapper request, RequestTimer requestTimer) {
+ request.setSessionAttribute(RequestTimer.SESSION_ATTR_ID, requestTimer);
+ }
+}