293222 improved statistics collection for async
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1022 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
a804e3ee7a
commit
b170e765f3
|
@ -12,6 +12,7 @@ jetty-7.0.1-SNAPSHOT
|
|||
+ 292642 Fix errors in embedded Jetty examples
|
||||
+ 292825 Continuations ISE rather than ignore bad transitions
|
||||
+ 292546 Proactively enforce HttpClient idle timeout
|
||||
+ 293222 Improved StatisticsHandler for async
|
||||
+ 293506 Unable to use jconsole with Jetty when running with security manager
|
||||
+ 293557 Add "jad" mime mapping
|
||||
+ JETTY-937 More JVM bug work arounds. Insert pause if all else fails
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
|
@ -53,6 +54,7 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||
|
|
|
@ -2,14 +2,22 @@ StatisticsHandler: Request Statistics gathering
|
|||
statsOnMs: Time in milliseconds stats have been collected for.
|
||||
statsReset(): Resets statistics.
|
||||
requests: Number of requests since statsReset() called.
|
||||
requestsExpired: Number of requests expired since statsReset() called.
|
||||
requestsResumed: Number of requests resumed since statsReset() called.
|
||||
requestTimeAverage: Average time in milliseconds of request handling since statsReset() called.
|
||||
requestTimeMin: Minimum time in milliseconds of request handling since statsReset() called.
|
||||
requestTimeMax: Maximum time in milliseconds of request handling since statsReset() called.
|
||||
requestTimeTotal: Total time in milliseconds of all request handling since statsReset() called.
|
||||
requestsActive: Number of requests currently active since statsReset() called.
|
||||
requestsActiveMax: Maximum number of active requests since statsReset() called.
|
||||
requestTimeMax: Maximum time in milliseconds of request handling since statsReset() called.
|
||||
requestTimeTotal: Total time in milliseconds of all request handling since statsReset() called.
|
||||
dispatched: Number of dispatches since statsReset() called.
|
||||
dispatchedActive: Number of dispatches currently active since statsReset() called.
|
||||
dispatchedActiveMax: Maximum number of active dispatches since statsReset() called.
|
||||
dispatchedTimeMax: Maximum time in milliseconds of dispatched handling since statsReset() called.
|
||||
dispatchedTimeTotal: Total time in milliseconds of all dispatched handling since statsReset() called.
|
||||
suspends: Number of requests suspended since statsReset() called.
|
||||
suspendsActive: Number of dispatches currently active since statsReset() called.
|
||||
suspendsActiveMax: Maximum number of active dispatches since statsReset() called.
|
||||
resumes: Number of requests resumed since statsReset() called.
|
||||
expires: Number of requests expired since statsReset() called.
|
||||
requestTimeAverage: Average time in milliseconds of request handling since statsReset() called.
|
||||
dispatchedTimeAverage: Average time in milliseconds of dispatch handling since statsReset() called.
|
||||
responses1xx: Number of responses with a 1xx status since statsReset() called.
|
||||
responses2xx: Number of responses with a 2xx status since statsReset() called.
|
||||
responses3xx: Number of responses with a 3xx status since statsReset() called.
|
||||
|
|
|
@ -675,6 +675,12 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
dispatch();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Request getBaseRequest()
|
||||
{
|
||||
return _connection.getRequest();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public ServletRequest getRequest()
|
||||
{
|
||||
|
|
|
@ -21,46 +21,87 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.continuation.Continuation;
|
||||
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||
import org.eclipse.jetty.server.AsyncContinuation;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
|
||||
public class StatisticsHandler extends HandlerWrapper
|
||||
{
|
||||
private transient final AtomicLong _statsStartedAt = new AtomicLong();
|
||||
private transient final AtomicInteger _requests = new AtomicInteger();
|
||||
private transient final AtomicInteger _resumedRequests = new AtomicInteger();
|
||||
private transient final AtomicInteger _expiredRequests = new AtomicInteger();
|
||||
private transient final AtomicLong _requestMinTime = new AtomicLong();
|
||||
private transient final AtomicLong _requestMaxTime = new AtomicLong();
|
||||
private transient final AtomicLong _requestTotalTime = new AtomicLong();
|
||||
private transient final AtomicLong _suspendMinTime = new AtomicLong();
|
||||
private transient final AtomicLong _suspendTotalTime = new AtomicLong();
|
||||
private transient final AtomicInteger _requestsActive = new AtomicInteger();
|
||||
private transient final AtomicInteger _requestsMaxActive = new AtomicInteger();
|
||||
private transient final AtomicInteger _responses1xx = new AtomicInteger();
|
||||
private transient final AtomicInteger _responses2xx = new AtomicInteger();
|
||||
private transient final AtomicInteger _responses3xx = new AtomicInteger();
|
||||
private transient final AtomicInteger _responses4xx = new AtomicInteger();
|
||||
private transient final AtomicInteger _responses5xx = new AtomicInteger();
|
||||
private transient final AtomicLong _responsesTotalBytes = new AtomicLong();
|
||||
private final AtomicLong _statsStartedAt = new AtomicLong();
|
||||
|
||||
private final AtomicInteger _requests = new AtomicInteger();
|
||||
private final AtomicInteger _requestsActive = new AtomicInteger();
|
||||
private final AtomicInteger _requestsActiveMax = new AtomicInteger();
|
||||
private final AtomicLong _requestTimeMax = new AtomicLong();
|
||||
private final AtomicLong _requestTimeTotal = new AtomicLong();
|
||||
|
||||
private final AtomicInteger _dispatched = new AtomicInteger();
|
||||
private final AtomicInteger _dispatchedActive = new AtomicInteger();
|
||||
private final AtomicInteger _dispatchedActiveMax = new AtomicInteger();
|
||||
private final AtomicLong _dispatchedTimeMax = new AtomicLong();
|
||||
private final AtomicLong _dispatchedTimeTotal = new AtomicLong();
|
||||
|
||||
private final AtomicInteger _suspends = new AtomicInteger();
|
||||
private final AtomicInteger _suspendsActive = new AtomicInteger();
|
||||
private final AtomicInteger _suspendsActiveMax = new AtomicInteger();
|
||||
private final AtomicInteger _resumes = new AtomicInteger();
|
||||
private final AtomicInteger _expires = new AtomicInteger();
|
||||
|
||||
private final AtomicInteger _responses1xx = new AtomicInteger();
|
||||
private final AtomicInteger _responses2xx = new AtomicInteger();
|
||||
private final AtomicInteger _responses3xx = new AtomicInteger();
|
||||
private final AtomicInteger _responses4xx = new AtomicInteger();
|
||||
private final AtomicInteger _responses5xx = new AtomicInteger();
|
||||
private final AtomicLong _responsesTotalBytes = new AtomicLong();
|
||||
|
||||
private final ContinuationListener _onCompletion = new ContinuationListener()
|
||||
{
|
||||
public void onComplete(Continuation continuation)
|
||||
{
|
||||
final Request request = ((AsyncContinuation)continuation).getBaseRequest();
|
||||
final long elapsed = System.currentTimeMillis()-request.getTimeStamp();
|
||||
|
||||
_requestsActive.decrementAndGet();
|
||||
_requests.incrementAndGet();
|
||||
updateMax(_requestTimeMax, elapsed);
|
||||
_requestTimeTotal.addAndGet(elapsed);
|
||||
updateResponse(request);
|
||||
if (!continuation.isResumed())
|
||||
_suspendsActive.decrementAndGet();
|
||||
}
|
||||
|
||||
public void onTimeout(Continuation continuation)
|
||||
{
|
||||
_expires.incrementAndGet();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the current request statistics.
|
||||
*/
|
||||
public void statsReset()
|
||||
{
|
||||
_statsStartedAt.set(System.currentTimeMillis());
|
||||
|
||||
_requests.set(0);
|
||||
_resumedRequests.set(0);
|
||||
_expiredRequests.set(0);
|
||||
_requestMinTime.set(Long.MAX_VALUE);
|
||||
_requestMaxTime.set(0L);
|
||||
_requestTotalTime.set(0L);
|
||||
_suspendMinTime.set(Long.MAX_VALUE);
|
||||
_suspendTotalTime.set(0L);
|
||||
_requestsActive.set(0);
|
||||
_requestsMaxActive.set(0);
|
||||
_requestsActiveMax.set(0);
|
||||
_requestTimeMax.set(0L);
|
||||
_requestTimeTotal.set(0L);
|
||||
|
||||
_dispatched.set(0);
|
||||
_dispatchedActive.set(0);
|
||||
_dispatchedActiveMax.set(0);
|
||||
_dispatchedTimeMax.set(0L);
|
||||
_dispatchedTimeTotal.set(0L);
|
||||
|
||||
_suspends.set(0);
|
||||
_suspendsActive.set(0);
|
||||
_suspendsActiveMax.set(0);
|
||||
_resumes.set(0);
|
||||
_expires.set(0);
|
||||
_responses1xx.set(0);
|
||||
_responses2xx.set(0);
|
||||
_responses3xx.set(0);
|
||||
|
@ -91,40 +132,26 @@ public class StatisticsHandler extends HandlerWrapper
|
|||
}
|
||||
}
|
||||
|
||||
private void updateMin(AtomicLong valueHolder, long value)
|
||||
{
|
||||
long oldValue = valueHolder.get();
|
||||
while (value < oldValue)
|
||||
{
|
||||
if (valueHolder.compareAndSet(oldValue, value))
|
||||
break;
|
||||
oldValue = valueHolder.get();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
_requests.incrementAndGet();
|
||||
updateMax(_dispatchedActiveMax, _dispatchedActive.incrementAndGet());
|
||||
|
||||
int activeRequests = _requestsActive.incrementAndGet();
|
||||
updateMax(_requestsMaxActive, activeRequests);
|
||||
|
||||
// The order of the ifs is important, as a continuation can be resumed and expired
|
||||
// We test first if it's expired, and then if it's resumed
|
||||
final long start;
|
||||
AsyncContinuation continuation = request.getAsyncContinuation();
|
||||
if (continuation.isExpired())
|
||||
if (continuation.isInitial())
|
||||
{
|
||||
_expiredRequests.incrementAndGet();
|
||||
// new request
|
||||
updateMax(_requestsActiveMax, _requestsActive.incrementAndGet());
|
||||
start = request.getTimeStamp();
|
||||
}
|
||||
else if (continuation.isResumed())
|
||||
else
|
||||
{
|
||||
_resumedRequests.incrementAndGet();
|
||||
|
||||
long initialTime = request.getTimeStamp();
|
||||
long suspendTime = System.currentTimeMillis() - initialTime;
|
||||
updateMin(_suspendMinTime, suspendTime);
|
||||
_suspendTotalTime.addAndGet(suspendTime);
|
||||
// resumed request
|
||||
start = System.currentTimeMillis();
|
||||
_suspendsActive.decrementAndGet();
|
||||
if (continuation.isResumed())
|
||||
_resumes.incrementAndGet();
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -133,23 +160,37 @@ public class StatisticsHandler extends HandlerWrapper
|
|||
}
|
||||
finally
|
||||
{
|
||||
_requestsActive.decrementAndGet();
|
||||
|
||||
if (!continuation.isSuspended())
|
||||
final long now = System.currentTimeMillis();
|
||||
final long dispatched=now-start;
|
||||
|
||||
_dispatchedActive.decrementAndGet();
|
||||
_dispatched.incrementAndGet();
|
||||
|
||||
_dispatchedTimeTotal.addAndGet(dispatched);
|
||||
updateMax(_dispatchedTimeMax, dispatched);
|
||||
|
||||
if (continuation.isSuspended())
|
||||
{
|
||||
if (continuation.isInitial())
|
||||
continuation.addContinuationListener(_onCompletion);
|
||||
_suspends.incrementAndGet();
|
||||
updateMax(_suspendsActiveMax, _suspendsActive.incrementAndGet());
|
||||
}
|
||||
else if (continuation.isInitial())
|
||||
{
|
||||
_requestsActive.decrementAndGet();
|
||||
_requests.incrementAndGet();
|
||||
|
||||
updateMax(_requestTimeMax, dispatched);
|
||||
_requestTimeTotal.addAndGet(dispatched);
|
||||
updateResponse(request);
|
||||
}
|
||||
// else onCompletion will handle it.
|
||||
}
|
||||
}
|
||||
|
||||
private void updateResponse(Request request)
|
||||
{
|
||||
long elapsed = System.currentTimeMillis() - request.getTimeStamp();
|
||||
|
||||
updateMin(_requestMinTime, elapsed);
|
||||
updateMax(_requestMaxTime, elapsed);
|
||||
_requestTotalTime.addAndGet(elapsed);
|
||||
|
||||
Response response = request.getResponse();
|
||||
switch (response.getStatus() / 100)
|
||||
{
|
||||
|
@ -171,7 +212,6 @@ public class StatisticsHandler extends HandlerWrapper
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_responsesTotalBytes.addAndGet(response.getContentCount());
|
||||
}
|
||||
|
||||
|
@ -184,9 +224,9 @@ public class StatisticsHandler extends HandlerWrapper
|
|||
|
||||
/**
|
||||
* @return the number of requests handled by this handler
|
||||
* since {@link #statsReset()} was last called, including
|
||||
* resumed requests
|
||||
* @see #getRequestsResumed()
|
||||
* since {@link #statsReset()} was last called, excluding
|
||||
* active requests
|
||||
* @see #getResumes()
|
||||
*/
|
||||
public int getRequests()
|
||||
{
|
||||
|
@ -208,25 +248,145 @@ public class StatisticsHandler extends HandlerWrapper
|
|||
*/
|
||||
public int getRequestsActiveMax()
|
||||
{
|
||||
return _requestsMaxActive.get();
|
||||
return _requestsActiveMax.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of requests that have been resumed
|
||||
* @see #getRequestsExpired()
|
||||
* @return the maximum time (in milliseconds) of request handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public int getRequestsResumed()
|
||||
public long getRequestTimeMax()
|
||||
{
|
||||
return _resumedRequests.get();
|
||||
return _requestTimeMax.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total time (in milliseconds) of requests handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public long getRequestTimeTotal()
|
||||
{
|
||||
return _requestTimeTotal.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the average time (in milliseconds) of request handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
* @see #getRequestTimeTotal()
|
||||
* @see #getRequests()
|
||||
*/
|
||||
public long getRequestTimeAverage()
|
||||
{
|
||||
int requests = getRequests();
|
||||
return requests == 0 ? 0 : getRequestTimeTotal() / requests;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of dispatches seen by this handler
|
||||
* since {@link #statsReset()} was last called, excluding
|
||||
* active dispatches
|
||||
*/
|
||||
public int getDispatched()
|
||||
{
|
||||
return _dispatched.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of dispatches currently in this handler
|
||||
* since {@link #statsReset()} was last called, including
|
||||
* resumed requests
|
||||
*/
|
||||
public int getDispatchedActive()
|
||||
{
|
||||
return _dispatchedActive.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the max number of dispatches currently in this handler
|
||||
* since {@link #statsReset()} was last called, including
|
||||
* resumed requests
|
||||
*/
|
||||
public int getDispatchedActiveMax()
|
||||
{
|
||||
return _dispatchedActiveMax.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum time (in milliseconds) of request dispatch
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public long getDispatchedTimeMax()
|
||||
{
|
||||
return _dispatchedTimeMax.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total time (in milliseconds) of requests handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public long getDispatchedTimeTotal()
|
||||
{
|
||||
return _dispatchedTimeTotal.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the average time (in milliseconds) of request handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
* @see #getRequestTimeTotal()
|
||||
* @see #getRequests()
|
||||
*/
|
||||
public long getDispatchedTimeAverage()
|
||||
{
|
||||
int requests = getDispatched();
|
||||
return requests == 0 ? 0 : getDispatchedTimeTotal() / requests;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the number of requests handled by this handler
|
||||
* since {@link #statsReset()} was last called, including
|
||||
* resumed requests
|
||||
* @see #getResumes()
|
||||
*/
|
||||
public int getSuspends()
|
||||
{
|
||||
return _suspends.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of requests currently suspended.
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public int getSuspendsActive()
|
||||
{
|
||||
return _suspendsActive.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum number of current suspended requests
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public int getSuspendsActiveMax()
|
||||
{
|
||||
return _suspendsActiveMax.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of requests that have been resumed
|
||||
* @see #getExpires()
|
||||
*/
|
||||
public int getResumes()
|
||||
{
|
||||
return _resumes.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of requests that expired while suspended.
|
||||
* @see #getRequestsResumed()
|
||||
* @see #getResumes()
|
||||
*/
|
||||
public int getRequestsExpired()
|
||||
public int getExpires()
|
||||
{
|
||||
return _expiredRequests.get();
|
||||
return _expires.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -281,46 +441,7 @@ public class StatisticsHandler extends HandlerWrapper
|
|||
{
|
||||
return System.currentTimeMillis() - _statsStartedAt.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minimum time (in milliseconds) of request handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public long getRequestTimeMin()
|
||||
{
|
||||
return _requestMinTime.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum time (in milliseconds) of request handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public long getRequestTimeMax()
|
||||
{
|
||||
return _requestMaxTime.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total time (in milliseconds) of requests handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public long getRequestTimeTotal()
|
||||
{
|
||||
return _requestTotalTime.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the average time (in milliseconds) of request handling
|
||||
* since {@link #statsReset()} was last called.
|
||||
* @see #getRequestTimeTotal()
|
||||
* @see #getRequests()
|
||||
*/
|
||||
public long getRequestTimeAverage()
|
||||
{
|
||||
int requests = getRequests();
|
||||
return requests == 0 ? 0 : getRequestTimeTotal() / requests;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the total bytes of content sent in responses
|
||||
*/
|
||||
|
@ -328,22 +449,45 @@ public class StatisticsHandler extends HandlerWrapper
|
|||
{
|
||||
return _responsesTotalBytes.get();
|
||||
}
|
||||
|
||||
public String toStatsHTML()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
/**
|
||||
* @return the minimum time (in milliseconds) of request suspension
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public long getSuspendedTimeMin()
|
||||
{
|
||||
return _suspendMinTime.get();
|
||||
}
|
||||
sb.append("<h1>Statistics:</h1>\n");
|
||||
sb.append("Statistics gathering started ").append(getStatsOnMs()).append("ms ago").append("<br />\n");
|
||||
|
||||
sb.append("<h2>Requests:</h2>\n");
|
||||
sb.append("Total requests: ").append(getRequests()).append("<br />\n");
|
||||
sb.append("Active requests: ").append(getRequestsActive()).append("<br />\n");
|
||||
sb.append("Max active requests: ").append(getRequestsActiveMax()).append("<br />\n");
|
||||
sb.append("Total requests time: ").append(getRequestTimeTotal()).append("<br />\n");
|
||||
sb.append("Average request time: ").append(getRequestTimeAverage()).append("<br />\n");
|
||||
sb.append("Max request time: ").append(getRequestTimeMax()).append("<br />\n");
|
||||
|
||||
|
||||
sb.append("<h2>Dispatches:</h2>\n");
|
||||
sb.append("Total dispatched: ").append(getDispatched()).append("<br />\n");
|
||||
sb.append("Active dispatched: ").append(getDispatchedActive()).append("<br />\n");
|
||||
sb.append("Max active dispatched: ").append(getDispatchedActiveMax()).append("<br />\n");
|
||||
sb.append("Total dispatched time: ").append(getDispatchedTimeTotal()).append("<br />\n");
|
||||
sb.append("Average dispatched time: ").append(getDispatchedTimeAverage()).append("<br />\n");
|
||||
sb.append("Max dispatched time: ").append(getDispatchedTimeMax()).append("<br />\n");
|
||||
|
||||
|
||||
sb.append("Total requests suspended: ").append(getSuspends()).append("<br />\n");
|
||||
sb.append("Total requests expired: ").append(getExpires()).append("<br />\n");
|
||||
sb.append("Total requests resumed: ").append(getResumes()).append("<br />\n");
|
||||
|
||||
sb.append("<h2>Responses:</h2>\n");
|
||||
sb.append("1xx responses: ").append(getResponses1xx()).append("<br />\n");
|
||||
sb.append("2xx responses: ").append(getResponses2xx()).append("<br />\n");
|
||||
sb.append("3xx responses: ").append(getResponses3xx()).append("<br />\n");
|
||||
sb.append("4xx responses: ").append(getResponses4xx()).append("<br />\n");
|
||||
sb.append("5xx responses: ").append(getResponses5xx()).append("<br />\n");
|
||||
sb.append("Bytes sent total: ").append(getResponsesBytesTotal()).append("<br />\n");
|
||||
|
||||
return sb.toString();
|
||||
|
||||
/**
|
||||
* @return the total time (in milliseconds) of request suspension
|
||||
* since {@link #statsReset()} was last called.
|
||||
*/
|
||||
public long getSuspendedTimeTotal()
|
||||
{
|
||||
return _suspendTotalTime.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.eclipse.jetty.server.handler;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
@ -25,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import junit.framework.TestCase;
|
||||
|
||||
import org.eclipse.jetty.continuation.Continuation;
|
||||
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||
import org.eclipse.jetty.continuation.ContinuationSupport;
|
||||
import org.eclipse.jetty.server.LocalConnector;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
@ -59,139 +61,10 @@ public class StatisticsHandlerTest extends TestCase
|
|||
_server.join();
|
||||
}
|
||||
|
||||
public void testSuspendResume() throws Exception
|
||||
public void testRequest() throws Exception
|
||||
{
|
||||
final long sleep = 500;
|
||||
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
|
||||
_statsHandler.setHandler(new AbstractHandler()
|
||||
{
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
|
||||
Continuation continuation = ContinuationSupport.getContinuation(httpRequest);
|
||||
if (continuationHandle.get() == null)
|
||||
{
|
||||
continuation.suspend();
|
||||
continuationHandle.set(continuation);
|
||||
try
|
||||
{
|
||||
Thread.sleep(sleep);
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
_server.start();
|
||||
|
||||
String request = "GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
_connector.executeRequest(request);
|
||||
boolean passed = _latchHandler.await(1000);
|
||||
assertTrue(passed);
|
||||
assertNotNull(continuationHandle.get());
|
||||
assertTrue(continuationHandle.get().isSuspended());
|
||||
|
||||
continuationHandle.get().resume();
|
||||
passed = _latchHandler.await(1000);
|
||||
assertTrue(passed);
|
||||
|
||||
assertEquals(2, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsResumed());
|
||||
assertEquals(0, _statsHandler.getRequestsExpired());
|
||||
assertEquals(1, _statsHandler.getResponses2xx());
|
||||
assertTrue(sleep <= _statsHandler.getSuspendedTimeMin());
|
||||
assertEquals(_statsHandler.getSuspendedTimeMin(), _statsHandler.getSuspendedTimeTotal());
|
||||
}
|
||||
|
||||
public void testSuspendExpire() throws Exception
|
||||
{
|
||||
final long timeout = 1000;
|
||||
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
|
||||
_statsHandler.setHandler(new AbstractHandler()
|
||||
{
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
|
||||
Continuation continuation = ContinuationSupport.getContinuation(httpRequest);
|
||||
System.out.println("continuation = " + continuation);
|
||||
if (continuationHandle.get() == null)
|
||||
{
|
||||
continuation.setTimeout(timeout);
|
||||
continuation.suspend();
|
||||
continuationHandle.set(continuation);
|
||||
}
|
||||
}
|
||||
});
|
||||
_server.start();
|
||||
|
||||
String request = "GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
_connector.executeRequest(request);
|
||||
boolean passed = _latchHandler.await(1000);
|
||||
assertTrue(passed);
|
||||
assertNotNull(continuationHandle.get());
|
||||
assertTrue(continuationHandle.get().isSuspended());
|
||||
|
||||
Thread.sleep(timeout);
|
||||
|
||||
passed = _latchHandler.await(1000);
|
||||
assertTrue(passed);
|
||||
|
||||
assertEquals(2, _statsHandler.getRequests());
|
||||
assertEquals(0, _statsHandler.getRequestsResumed());
|
||||
assertEquals(1, _statsHandler.getRequestsExpired());
|
||||
assertEquals(1, _statsHandler.getResponses2xx());
|
||||
}
|
||||
|
||||
public void testSuspendComplete() throws Exception
|
||||
{
|
||||
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
|
||||
_statsHandler.setHandler(new AbstractHandler()
|
||||
{
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
|
||||
Continuation continuation = ContinuationSupport.getContinuation(httpRequest);
|
||||
if (continuationHandle.get() == null)
|
||||
{
|
||||
continuation.suspend();
|
||||
continuationHandle.set(continuation);
|
||||
}
|
||||
}
|
||||
});
|
||||
_server.start();
|
||||
|
||||
String request = "GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
_connector.executeRequest(request);
|
||||
boolean passed = _latchHandler.await(1000);
|
||||
assertTrue(passed);
|
||||
assertNotNull(continuationHandle.get());
|
||||
assertTrue(continuationHandle.get().isSuspended());
|
||||
|
||||
continuationHandle.get().complete();
|
||||
|
||||
assertEquals(1, _statsHandler.getRequests());
|
||||
assertEquals(0, _statsHandler.getRequestsResumed());
|
||||
assertEquals(0, _statsHandler.getRequestsExpired());
|
||||
// TODO: complete callback not implemented
|
||||
// Commented to pass the tests
|
||||
// assertEquals(1, _statsHandler.getResponses2xx());
|
||||
}
|
||||
|
||||
public void testRequestTimes() throws Exception
|
||||
{
|
||||
final long sleep = 1000;
|
||||
final CyclicBarrier barrier[] = { new CyclicBarrier(2), new CyclicBarrier(2)};
|
||||
|
||||
_statsHandler.setHandler(new AbstractHandler()
|
||||
{
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
|
@ -199,9 +72,11 @@ public class StatisticsHandlerTest extends TestCase
|
|||
request.setHandled(true);
|
||||
try
|
||||
{
|
||||
Thread.sleep(sleep);
|
||||
barrier[0].await();
|
||||
barrier[1].await();
|
||||
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
catch (Exception x)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
|
@ -213,24 +88,452 @@ public class StatisticsHandlerTest extends TestCase
|
|||
String request = "GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
_connector.getResponses(request);
|
||||
_connector.executeRequest(request);
|
||||
|
||||
barrier[0].await();
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getRequestsActiveMax());
|
||||
|
||||
assertEquals(0, _statsHandler.getDispatched());
|
||||
assertEquals(1, _statsHandler.getDispatchedActive());
|
||||
assertEquals(1, _statsHandler.getDispatchedActiveMax());
|
||||
|
||||
|
||||
barrier[1].await();
|
||||
boolean passed = _latchHandler.await(1000);
|
||||
assertTrue(passed);
|
||||
|
||||
assertEquals(1, _statsHandler.getRequests());
|
||||
assertEquals(0, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getRequestsActiveMax());
|
||||
|
||||
assertEquals(1, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
assertEquals(1, _statsHandler.getDispatchedActiveMax());
|
||||
|
||||
assertEquals(0, _statsHandler.getSuspends());
|
||||
assertEquals(0, _statsHandler.getResumes());
|
||||
assertEquals(0, _statsHandler.getExpires());
|
||||
assertEquals(1, _statsHandler.getResponses2xx());
|
||||
assertTrue(sleep <= _statsHandler.getRequestTimeMin());
|
||||
assertEquals(_statsHandler.getRequestTimeMin(), _statsHandler.getRequestTimeMax());
|
||||
assertEquals(_statsHandler.getRequestTimeMin(), _statsHandler.getRequestTimeTotal());
|
||||
assertEquals(_statsHandler.getRequestTimeMin(), _statsHandler.getRequestTimeAverage());
|
||||
|
||||
_latchHandler.reset();
|
||||
barrier[0].reset();
|
||||
barrier[1].reset();
|
||||
|
||||
_connector.executeRequest(request);
|
||||
|
||||
_connector.getResponses(request);
|
||||
barrier[0].await();
|
||||
|
||||
assertEquals(1, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getRequestsActiveMax());
|
||||
|
||||
assertEquals(1, _statsHandler.getDispatched());
|
||||
assertEquals(1, _statsHandler.getDispatchedActive());
|
||||
assertEquals(1, _statsHandler.getDispatchedActiveMax());
|
||||
|
||||
|
||||
barrier[1].await();
|
||||
passed = _latchHandler.await(1000);
|
||||
assertTrue(passed);
|
||||
|
||||
assertEquals(2, _statsHandler.getRequests());
|
||||
assertEquals(0, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getRequestsActiveMax());
|
||||
|
||||
assertEquals(2, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
assertEquals(1, _statsHandler.getDispatchedActiveMax());
|
||||
|
||||
assertEquals(0, _statsHandler.getSuspends());
|
||||
assertEquals(0, _statsHandler.getResumes());
|
||||
assertEquals(0, _statsHandler.getExpires());
|
||||
assertEquals(2, _statsHandler.getResponses2xx());
|
||||
assertTrue(sleep <= _statsHandler.getRequestTimeMin());
|
||||
assertTrue(sleep <= _statsHandler.getRequestTimeAverage());
|
||||
assertTrue(_statsHandler.getRequestTimeTotal() >= 2 * sleep);
|
||||
|
||||
_latchHandler.reset(2);
|
||||
barrier[0]=new CyclicBarrier(3);
|
||||
barrier[1]=new CyclicBarrier(3);
|
||||
|
||||
_connector.executeRequest(request);
|
||||
_connector.executeRequest(request);
|
||||
|
||||
barrier[0].await();
|
||||
|
||||
assertEquals(2, _statsHandler.getRequests());
|
||||
assertEquals(2, _statsHandler.getRequestsActive());
|
||||
assertEquals(2, _statsHandler.getRequestsActiveMax());
|
||||
|
||||
assertEquals(2, _statsHandler.getDispatched());
|
||||
assertEquals(2, _statsHandler.getDispatchedActive());
|
||||
assertEquals(2, _statsHandler.getDispatchedActiveMax());
|
||||
|
||||
|
||||
barrier[1].await();
|
||||
passed = _latchHandler.await(1000);
|
||||
assertTrue(passed);
|
||||
|
||||
assertEquals(4, _statsHandler.getRequests());
|
||||
assertEquals(0, _statsHandler.getRequestsActive());
|
||||
assertEquals(2, _statsHandler.getRequestsActiveMax());
|
||||
|
||||
assertEquals(4, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
assertEquals(2, _statsHandler.getDispatchedActiveMax());
|
||||
|
||||
assertEquals(0, _statsHandler.getSuspends());
|
||||
assertEquals(0, _statsHandler.getResumes());
|
||||
assertEquals(0, _statsHandler.getExpires());
|
||||
assertEquals(4, _statsHandler.getResponses2xx());
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void testSuspendResume() throws Exception
|
||||
{
|
||||
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
|
||||
final CyclicBarrier barrier[] = { new CyclicBarrier(2), new CyclicBarrier(2), new CyclicBarrier(2)};
|
||||
_statsHandler.setHandler(new AbstractHandler()
|
||||
{
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
|
||||
try
|
||||
{
|
||||
barrier[0].await();
|
||||
Thread.sleep(10);
|
||||
Continuation continuation = ContinuationSupport.getContinuation(httpRequest);
|
||||
if (continuationHandle.get() == null)
|
||||
{
|
||||
continuation.suspend();
|
||||
continuationHandle.set(continuation);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
barrier[1].await();
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
_server.start();
|
||||
|
||||
String request = "GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
_connector.executeRequest(request);
|
||||
|
||||
|
||||
barrier[0].await();
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
|
||||
assertEquals(0, _statsHandler.getDispatched());
|
||||
assertEquals(1, _statsHandler.getDispatchedActive());
|
||||
|
||||
barrier[1].await();
|
||||
assertTrue(_latchHandler.await(1000));
|
||||
assertNotNull(continuationHandle.get());
|
||||
assertTrue(continuationHandle.get().isSuspended());
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
|
||||
Thread.sleep(10);
|
||||
_latchHandler.reset();
|
||||
barrier[0].reset();
|
||||
barrier[1].reset();
|
||||
|
||||
continuationHandle.get().addContinuationListener(new ContinuationListener()
|
||||
{
|
||||
public void onTimeout(Continuation continuation)
|
||||
{
|
||||
}
|
||||
|
||||
public void onComplete(Continuation continuation)
|
||||
{
|
||||
try { barrier[2].await(); } catch(Exception e) {}
|
||||
}
|
||||
});
|
||||
|
||||
continuationHandle.get().resume();
|
||||
|
||||
|
||||
barrier[0].await();
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getDispatched());
|
||||
assertEquals(1, _statsHandler.getDispatchedActive());
|
||||
|
||||
barrier[1].await();
|
||||
assertTrue(_latchHandler.await(1000));
|
||||
barrier[2].await();
|
||||
|
||||
assertEquals(1, _statsHandler.getRequests());
|
||||
assertEquals(0, _statsHandler.getRequestsActive());
|
||||
assertEquals(2, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
|
||||
|
||||
assertEquals(1, _statsHandler.getSuspends());
|
||||
assertEquals(1, _statsHandler.getResumes());
|
||||
assertEquals(0, _statsHandler.getExpires());
|
||||
assertEquals(1, _statsHandler.getResponses2xx());
|
||||
|
||||
|
||||
assertTrue(_statsHandler.getRequestTimeTotal()>=30);
|
||||
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMax());
|
||||
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeAverage());
|
||||
|
||||
assertTrue(_statsHandler.getDispatchedTimeTotal()>=20);
|
||||
assertTrue(_statsHandler.getDispatchedTimeAverage()+10<=_statsHandler.getDispatchedTimeTotal());
|
||||
assertTrue(_statsHandler.getDispatchedTimeMax()+10<=_statsHandler.getDispatchedTimeTotal());
|
||||
|
||||
}
|
||||
|
||||
public void testSuspendExpire() throws Exception
|
||||
{
|
||||
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
|
||||
final CyclicBarrier barrier[] = { new CyclicBarrier(2), new CyclicBarrier(2), new CyclicBarrier(2)};
|
||||
_statsHandler.setHandler(new AbstractHandler()
|
||||
{
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
|
||||
try
|
||||
{
|
||||
barrier[0].await();
|
||||
Thread.sleep(10);
|
||||
Continuation continuation = ContinuationSupport.getContinuation(httpRequest);
|
||||
if (continuationHandle.get() == null)
|
||||
{
|
||||
continuation.setTimeout(10);
|
||||
continuation.suspend();
|
||||
continuationHandle.set(continuation);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
barrier[1].await();
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
_server.start();
|
||||
|
||||
String request = "GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
_connector.executeRequest(request);
|
||||
|
||||
|
||||
barrier[0].await();
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
|
||||
assertEquals(0, _statsHandler.getDispatched());
|
||||
assertEquals(1, _statsHandler.getDispatchedActive());
|
||||
|
||||
barrier[1].await();
|
||||
assertTrue(_latchHandler.await(1000));
|
||||
assertNotNull(continuationHandle.get());
|
||||
assertTrue(continuationHandle.get().isSuspended());
|
||||
|
||||
continuationHandle.get().addContinuationListener(new ContinuationListener()
|
||||
{
|
||||
public void onTimeout(Continuation continuation)
|
||||
{
|
||||
}
|
||||
|
||||
public void onComplete(Continuation continuation)
|
||||
{
|
||||
try { barrier[2].await(); } catch(Exception e) {}
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
|
||||
_latchHandler.reset();
|
||||
barrier[0].reset();
|
||||
barrier[1].reset();
|
||||
|
||||
barrier[0].await();
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getDispatched());
|
||||
assertEquals(1, _statsHandler.getDispatchedActive());
|
||||
|
||||
barrier[1].await();
|
||||
assertTrue(_latchHandler.await(1000));
|
||||
barrier[2].await();
|
||||
|
||||
assertEquals(1, _statsHandler.getRequests());
|
||||
assertEquals(0, _statsHandler.getRequestsActive());
|
||||
assertEquals(2, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
|
||||
assertEquals(1, _statsHandler.getSuspends());
|
||||
assertEquals(1, _statsHandler.getResumes());
|
||||
assertEquals(1, _statsHandler.getExpires());
|
||||
assertEquals(1, _statsHandler.getResponses2xx());
|
||||
|
||||
|
||||
assertTrue(_statsHandler.getRequestTimeTotal()>=30);
|
||||
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMax());
|
||||
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeAverage());
|
||||
|
||||
assertTrue(_statsHandler.getDispatchedTimeTotal()>=20);
|
||||
assertTrue(_statsHandler.getDispatchedTimeAverage()+10<=_statsHandler.getDispatchedTimeTotal());
|
||||
assertTrue(_statsHandler.getDispatchedTimeMax()+10<=_statsHandler.getDispatchedTimeTotal());
|
||||
|
||||
}
|
||||
|
||||
public void testSuspendComplete() throws Exception
|
||||
{
|
||||
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
|
||||
final CyclicBarrier barrier[] = { new CyclicBarrier(2), new CyclicBarrier(2), new CyclicBarrier(2)};
|
||||
_statsHandler.setHandler(new AbstractHandler()
|
||||
{
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
|
||||
try
|
||||
{
|
||||
barrier[0].await();
|
||||
Thread.sleep(10);
|
||||
Continuation continuation = ContinuationSupport.getContinuation(httpRequest);
|
||||
if (continuationHandle.get() == null)
|
||||
{
|
||||
continuation.setTimeout(1000);
|
||||
continuation.suspend();
|
||||
continuationHandle.set(continuation);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
barrier[1].await();
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
_server.start();
|
||||
|
||||
String request = "GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
_connector.executeRequest(request);
|
||||
|
||||
|
||||
barrier[0].await();
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
|
||||
assertEquals(0, _statsHandler.getDispatched());
|
||||
assertEquals(1, _statsHandler.getDispatchedActive());
|
||||
|
||||
|
||||
barrier[1].await();
|
||||
assertTrue(_latchHandler.await(1000));
|
||||
assertNotNull(continuationHandle.get());
|
||||
assertTrue(continuationHandle.get().isSuspended());
|
||||
continuationHandle.get().addContinuationListener(new ContinuationListener()
|
||||
{
|
||||
public void onTimeout(Continuation continuation)
|
||||
{
|
||||
}
|
||||
|
||||
public void onComplete(Continuation continuation)
|
||||
{
|
||||
try { barrier[2].await(); } catch(Exception e) {}
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(0, _statsHandler.getRequests());
|
||||
assertEquals(1, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
|
||||
Thread.sleep(10);
|
||||
continuationHandle.get().complete();
|
||||
barrier[2].await();
|
||||
|
||||
assertEquals(1, _statsHandler.getRequests());
|
||||
assertEquals(0, _statsHandler.getRequestsActive());
|
||||
assertEquals(1, _statsHandler.getDispatched());
|
||||
assertEquals(0, _statsHandler.getDispatchedActive());
|
||||
|
||||
assertEquals(1, _statsHandler.getSuspends());
|
||||
assertEquals(0, _statsHandler.getResumes());
|
||||
assertEquals(0, _statsHandler.getExpires());
|
||||
assertEquals(1, _statsHandler.getResponses2xx());
|
||||
|
||||
assertTrue(_statsHandler.getRequestTimeTotal()>=20);
|
||||
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMax());
|
||||
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeAverage());
|
||||
|
||||
assertTrue(_statsHandler.getDispatchedTimeTotal()>=10);
|
||||
assertTrue(_statsHandler.getDispatchedTimeTotal()<_statsHandler.getRequestTimeTotal());
|
||||
assertEquals(_statsHandler.getDispatchedTimeTotal(),_statsHandler.getDispatchedTimeMax());
|
||||
assertEquals(_statsHandler.getDispatchedTimeTotal(),_statsHandler.getDispatchedTimeAverage());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This handler is external to the statistics handler and it is used to ensure that statistics handler's
|
||||
* handle() is fully executed before asserting its values in the tests, to avoid race conditions with the
|
||||
|
@ -238,11 +541,12 @@ public class StatisticsHandlerTest extends TestCase
|
|||
*/
|
||||
private static class LatchHandler extends HandlerWrapper
|
||||
{
|
||||
private volatile CountDownLatch latch = new CountDownLatch(1);
|
||||
private volatile CountDownLatch _latch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
final CountDownLatch latch=_latch;
|
||||
try
|
||||
{
|
||||
super.handle(path, request, httpRequest, httpResponse);
|
||||
|
@ -253,11 +557,19 @@ public class StatisticsHandlerTest extends TestCase
|
|||
}
|
||||
}
|
||||
|
||||
private void reset()
|
||||
{
|
||||
_latch=new CountDownLatch(1);
|
||||
}
|
||||
|
||||
private void reset(int count)
|
||||
{
|
||||
_latch=new CountDownLatch(count);
|
||||
}
|
||||
|
||||
private boolean await(long ms) throws InterruptedException
|
||||
{
|
||||
boolean result = latch.await(ms, TimeUnit.MILLISECONDS);
|
||||
latch = new CountDownLatch(1);
|
||||
return result;
|
||||
return _latch.await(ms, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,17 +111,24 @@ public class StatisticsServlet extends HttpServlet
|
|||
|
||||
sb.append(" <requests>\n");
|
||||
sb.append(" <statsOnMs>").append(_statsHandler.getStatsOnMs()).append("</statsOnMs>\n");
|
||||
|
||||
sb.append(" <requests>").append(_statsHandler.getRequests()).append("</requests>\n");
|
||||
sb.append(" <requestsExpired>").append(_statsHandler.getRequestsExpired()).append("</requestsExpired>\n");
|
||||
sb.append(" <requestsResumed>").append(_statsHandler.getRequestsResumed()).append("</requestsResumed>\n");
|
||||
sb.append(" <requestsActive>").append(_statsHandler.getRequestsActive()).append("</requestsActive>\n");
|
||||
sb.append(" <requestsActiveMax>").append(_statsHandler.getRequestsActiveMax()).append("</requestsActiveMax>\n");
|
||||
sb.append(" <requestsTimeTotal>").append(_statsHandler.getRequestTimeTotal()).append("</requestsTimeTotal>\n");
|
||||
sb.append(" <requestsTimeAverage>").append(_statsHandler.getRequestTimeAverage()).append("</requestsTimeAverage>\n");
|
||||
sb.append(" <requestsTimeMin>").append(_statsHandler.getRequestTimeMin()).append("</requestsTimeMin>\n");
|
||||
sb.append(" <requestsTimeMax>").append(_statsHandler.getRequestTimeMax()).append("</requestsTimeMax>\n");
|
||||
sb.append(" <suspendTimeMin>").append(_statsHandler.getSuspendedTimeMin()).append("</suspendTimeMin>\n");
|
||||
sb.append(" <suspendTimeTotal>").append(_statsHandler.getSuspendedTimeTotal()).append("</suspendTimeTotal>\n");
|
||||
|
||||
sb.append(" <dispatched>").append(_statsHandler.getDispatched()).append("</dispatched>\n");
|
||||
sb.append(" <dispatchedActive>").append(_statsHandler.getDispatchedActive()).append("</dispatchedActive>\n");
|
||||
sb.append(" <dispatchedActiveMax>").append(_statsHandler.getDispatchedActiveMax()).append("</dispatchedActiveMax>\n");
|
||||
sb.append(" <dispatchedTimeTotal>").append(_statsHandler.getDispatchedTimeTotal()).append("</dispatchedTimeTotal>\n");
|
||||
sb.append(" <dispatchedTimeAverage>").append(_statsHandler.getDispatchedTimeAverage()).append("</dispatchedTimeAverage>\n");
|
||||
sb.append(" <dispatchedTimeMax>").append(_statsHandler.getDispatchedTimeMax()).append("</dispatchedTimeMax>\n");
|
||||
|
||||
sb.append(" <requestsSuspended>").append(_statsHandler.getSuspends()).append("</requestsSuspended>\n");
|
||||
sb.append(" <requestsExpired>").append(_statsHandler.getExpires()).append("</requestsExpired>\n");
|
||||
sb.append(" <requestsResumed>").append(_statsHandler.getResumes()).append("</requestsResumed>\n");
|
||||
sb.append(" </requests>\n");
|
||||
|
||||
sb.append(" <responses>\n");
|
||||
|
@ -173,32 +180,8 @@ public class StatisticsServlet extends HttpServlet
|
|||
|
||||
private void sendTextResponse(HttpServletResponse response) throws IOException
|
||||
{
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("<h1>Statistics:</h1>\n");
|
||||
|
||||
sb.append("<h2>Requests:</h2>\n");
|
||||
sb.append("Statistics gathering started ").append(_statsHandler.getStatsOnMs()).append("ms ago").append("<br />\n");
|
||||
sb.append("Total requests: ").append(_statsHandler.getRequests()).append("<br />\n");
|
||||
sb.append("Total requests expired: ").append(_statsHandler.getRequestsExpired()).append("<br />\n");
|
||||
sb.append("Total requests resumed: ").append(_statsHandler.getRequestsResumed()).append("<br />\n");
|
||||
sb.append("Current requests active: ").append(_statsHandler.getRequestsActive()).append("<br />\n");
|
||||
sb.append("Max concurrent requests active: ").append(_statsHandler.getRequestsActiveMax()).append("<br />\n");
|
||||
sb.append("Total requests time: ").append(_statsHandler.getRequestTimeTotal()).append("<br />\n");
|
||||
sb.append("Average request time: ").append(_statsHandler.getRequestTimeAverage()).append("<br />\n");
|
||||
sb.append("Min request time: ").append(_statsHandler.getRequestTimeMin()).append("<br />\n");
|
||||
sb.append("Max request time: ").append(_statsHandler.getRequestTimeMax()).append("<br />\n");
|
||||
sb.append("Min suspended request time: ").append(_statsHandler.getSuspendedTimeMin()).append("<br />\n");
|
||||
sb.append("Total suspended requests time: ").append(_statsHandler.getSuspendedTimeTotal()).append("<br />\n");
|
||||
|
||||
sb.append("<h2>Responses:</h2>\n");
|
||||
sb.append("1xx responses: ").append(_statsHandler.getResponses1xx()).append("<br />\n");
|
||||
sb.append("2xx responses: ").append(_statsHandler.getResponses2xx()).append("<br />\n");
|
||||
sb.append("3xx responses: ").append(_statsHandler.getResponses3xx()).append("<br />\n");
|
||||
sb.append("4xx responses: ").append(_statsHandler.getResponses4xx()).append("<br />\n");
|
||||
sb.append("5xx responses: ").append(_statsHandler.getResponses5xx()).append("<br />\n");
|
||||
sb.append("Bytes sent total: ").append(_statsHandler.getResponsesBytesTotal()).append("<br />\n");
|
||||
sb.append(_statsHandler.toStatsHTML());
|
||||
|
||||
sb.append("<h2>Connections:</h2>\n");
|
||||
for (Connector connector : _connectors)
|
||||
|
|
|
@ -65,11 +65,6 @@
|
|||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
|
|
@ -52,6 +52,7 @@ public class Dump extends HttpServlet
|
|||
{
|
||||
static boolean fixed;
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException
|
||||
{
|
||||
super.init(config);
|
||||
|
@ -131,26 +132,12 @@ public class Dump extends HttpServlet
|
|||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
Continuation continuation = ContinuationSupport.getContinuation(request,response);
|
||||
Continuation continuation = ContinuationSupport.getContinuation(request);
|
||||
continuation.resume();
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
if (request.getParameter("suspend")!=null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Continuation continuation = ContinuationSupport.getContinuation(request,response);
|
||||
continuation.setTimeout(Long.parseLong(request.getParameter("suspend")));
|
||||
continuation.suspend();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.getParameter("complete")!=null)
|
||||
{
|
||||
|
@ -183,6 +170,21 @@ public class Dump extends HttpServlet
|
|||
}).start();
|
||||
}
|
||||
|
||||
if (request.getParameter("suspend")!=null && request.getAttribute("SUSPEND")!=Boolean.TRUE)
|
||||
{
|
||||
request.setAttribute("SUSPEND",Boolean.TRUE);
|
||||
try
|
||||
{
|
||||
Continuation continuation = ContinuationSupport.getContinuation(request);
|
||||
continuation.setTimeout(Long.parseLong(request.getParameter("suspend")));
|
||||
continuation.suspend();
|
||||
continuation.undispatch();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
|
||||
request.setAttribute("Dump", this);
|
||||
getServletContext().setAttribute("Dump",this);
|
||||
|
|
|
@ -31,7 +31,7 @@ This is a test context that serves:
|
|||
<li>a <a href="dispatch">Dispatcher Servlet</a></li>
|
||||
<li>a <a href="rewrite/">Request Rewrite Servlet</a></li>
|
||||
<li>a <a href="google/">Transparent Proxy</a> (to www.google.com)</li>
|
||||
<li>a <a href="cgi-bin/hello.sh">CGI script</a> (unix only)</li>
|
||||
<li>a <a href="chat/">Comet Chat</a></li>
|
||||
<li>a <a href="auth.html">Authentication</a></li>
|
||||
</ul>
|
||||
<p/>
|
||||
|
|
Loading…
Reference in New Issue