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
|
+ 292642 Fix errors in embedded Jetty examples
|
||||||
+ 292825 Continuations ISE rather than ignore bad transitions
|
+ 292825 Continuations ISE rather than ignore bad transitions
|
||||||
+ 292546 Proactively enforce HttpClient idle timeout
|
+ 292546 Proactively enforce HttpClient idle timeout
|
||||||
|
+ 293222 Improved StatisticsHandler for async
|
||||||
+ 293506 Unable to use jconsole with Jetty when running with security manager
|
+ 293506 Unable to use jconsole with Jetty when running with security manager
|
||||||
+ 293557 Add "jad" mime mapping
|
+ 293557 Add "jad" mime mapping
|
||||||
+ JETTY-937 More JVM bug work arounds. Insert pause if all else fails
|
+ JETTY-937 More JVM bug work arounds. Insert pause if all else fails
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!--
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||||
|
|
|
@ -2,14 +2,22 @@ StatisticsHandler: Request Statistics gathering
|
||||||
statsOnMs: Time in milliseconds stats have been collected for.
|
statsOnMs: Time in milliseconds stats have been collected for.
|
||||||
statsReset(): Resets statistics.
|
statsReset(): Resets statistics.
|
||||||
requests: Number of requests since statsReset() called.
|
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.
|
requestsActive: Number of requests currently active since statsReset() called.
|
||||||
requestsActiveMax: Maximum number of active requests 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.
|
responses1xx: Number of responses with a 1xx status since statsReset() called.
|
||||||
responses2xx: Number of responses with a 2xx 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.
|
responses3xx: Number of responses with a 3xx status since statsReset() called.
|
||||||
|
|
|
@ -675,6 +675,12 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
||||||
dispatch();
|
dispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public Request getBaseRequest()
|
||||||
|
{
|
||||||
|
return _connection.getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public ServletRequest getRequest()
|
public ServletRequest getRequest()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,29 +21,62 @@ import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
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.AsyncContinuation;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
import org.eclipse.jetty.server.Response;
|
import org.eclipse.jetty.server.Response;
|
||||||
|
|
||||||
public class StatisticsHandler extends HandlerWrapper
|
public class StatisticsHandler extends HandlerWrapper
|
||||||
{
|
{
|
||||||
private transient final AtomicLong _statsStartedAt = new AtomicLong();
|
private final AtomicLong _statsStartedAt = new AtomicLong();
|
||||||
private transient final AtomicInteger _requests = new AtomicInteger();
|
|
||||||
private transient final AtomicInteger _resumedRequests = new AtomicInteger();
|
private final AtomicInteger _requests = new AtomicInteger();
|
||||||
private transient final AtomicInteger _expiredRequests = new AtomicInteger();
|
private final AtomicInteger _requestsActive = new AtomicInteger();
|
||||||
private transient final AtomicLong _requestMinTime = new AtomicLong();
|
private final AtomicInteger _requestsActiveMax = new AtomicInteger();
|
||||||
private transient final AtomicLong _requestMaxTime = new AtomicLong();
|
private final AtomicLong _requestTimeMax = new AtomicLong();
|
||||||
private transient final AtomicLong _requestTotalTime = new AtomicLong();
|
private final AtomicLong _requestTimeTotal = new AtomicLong();
|
||||||
private transient final AtomicLong _suspendMinTime = new AtomicLong();
|
|
||||||
private transient final AtomicLong _suspendTotalTime = new AtomicLong();
|
private final AtomicInteger _dispatched = new AtomicInteger();
|
||||||
private transient final AtomicInteger _requestsActive = new AtomicInteger();
|
private final AtomicInteger _dispatchedActive = new AtomicInteger();
|
||||||
private transient final AtomicInteger _requestsMaxActive = new AtomicInteger();
|
private final AtomicInteger _dispatchedActiveMax = new AtomicInteger();
|
||||||
private transient final AtomicInteger _responses1xx = new AtomicInteger();
|
private final AtomicLong _dispatchedTimeMax = new AtomicLong();
|
||||||
private transient final AtomicInteger _responses2xx = new AtomicInteger();
|
private final AtomicLong _dispatchedTimeTotal = new AtomicLong();
|
||||||
private transient final AtomicInteger _responses3xx = new AtomicInteger();
|
|
||||||
private transient final AtomicInteger _responses4xx = new AtomicInteger();
|
private final AtomicInteger _suspends = new AtomicInteger();
|
||||||
private transient final AtomicInteger _responses5xx = new AtomicInteger();
|
private final AtomicInteger _suspendsActive = new AtomicInteger();
|
||||||
private transient final AtomicLong _responsesTotalBytes = new AtomicLong();
|
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.
|
* Resets the current request statistics.
|
||||||
|
@ -51,16 +84,24 @@ public class StatisticsHandler extends HandlerWrapper
|
||||||
public void statsReset()
|
public void statsReset()
|
||||||
{
|
{
|
||||||
_statsStartedAt.set(System.currentTimeMillis());
|
_statsStartedAt.set(System.currentTimeMillis());
|
||||||
|
|
||||||
_requests.set(0);
|
_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);
|
_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);
|
_responses1xx.set(0);
|
||||||
_responses2xx.set(0);
|
_responses2xx.set(0);
|
||||||
_responses3xx.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
|
@Override
|
||||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
_requests.incrementAndGet();
|
updateMax(_dispatchedActiveMax, _dispatchedActive.incrementAndGet());
|
||||||
|
|
||||||
int activeRequests = _requestsActive.incrementAndGet();
|
final long start;
|
||||||
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
|
|
||||||
AsyncContinuation continuation = request.getAsyncContinuation();
|
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();
|
// resumed request
|
||||||
|
start = System.currentTimeMillis();
|
||||||
long initialTime = request.getTimeStamp();
|
_suspendsActive.decrementAndGet();
|
||||||
long suspendTime = System.currentTimeMillis() - initialTime;
|
if (continuation.isResumed())
|
||||||
updateMin(_suspendMinTime, suspendTime);
|
_resumes.incrementAndGet();
|
||||||
_suspendTotalTime.addAndGet(suspendTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -133,23 +160,37 @@ public class StatisticsHandler extends HandlerWrapper
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_requestsActive.decrementAndGet();
|
final long now = System.currentTimeMillis();
|
||||||
|
final long dispatched=now-start;
|
||||||
|
|
||||||
if (!continuation.isSuspended())
|
_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);
|
updateResponse(request);
|
||||||
}
|
}
|
||||||
|
// else onCompletion will handle it.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateResponse(Request request)
|
private void updateResponse(Request request)
|
||||||
{
|
{
|
||||||
long elapsed = System.currentTimeMillis() - request.getTimeStamp();
|
|
||||||
|
|
||||||
updateMin(_requestMinTime, elapsed);
|
|
||||||
updateMax(_requestMaxTime, elapsed);
|
|
||||||
_requestTotalTime.addAndGet(elapsed);
|
|
||||||
|
|
||||||
Response response = request.getResponse();
|
Response response = request.getResponse();
|
||||||
switch (response.getStatus() / 100)
|
switch (response.getStatus() / 100)
|
||||||
{
|
{
|
||||||
|
@ -171,7 +212,6 @@ public class StatisticsHandler extends HandlerWrapper
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_responsesTotalBytes.addAndGet(response.getContentCount());
|
_responsesTotalBytes.addAndGet(response.getContentCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,9 +224,9 @@ public class StatisticsHandler extends HandlerWrapper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of requests handled by this handler
|
* @return the number of requests handled by this handler
|
||||||
* since {@link #statsReset()} was last called, including
|
* since {@link #statsReset()} was last called, excluding
|
||||||
* resumed requests
|
* active requests
|
||||||
* @see #getRequestsResumed()
|
* @see #getResumes()
|
||||||
*/
|
*/
|
||||||
public int getRequests()
|
public int getRequests()
|
||||||
{
|
{
|
||||||
|
@ -208,25 +248,145 @@ public class StatisticsHandler extends HandlerWrapper
|
||||||
*/
|
*/
|
||||||
public int getRequestsActiveMax()
|
public int getRequestsActiveMax()
|
||||||
{
|
{
|
||||||
return _requestsMaxActive.get();
|
return _requestsActiveMax.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maximum time (in milliseconds) of request handling
|
||||||
|
* since {@link #statsReset()} was last called.
|
||||||
|
*/
|
||||||
|
public long getRequestTimeMax()
|
||||||
|
{
|
||||||
|
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
|
* @return the number of requests that have been resumed
|
||||||
* @see #getRequestsExpired()
|
* @see #getExpires()
|
||||||
*/
|
*/
|
||||||
public int getRequestsResumed()
|
public int getResumes()
|
||||||
{
|
{
|
||||||
return _resumedRequests.get();
|
return _resumes.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of requests that expired while suspended.
|
* @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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,45 +442,6 @@ public class StatisticsHandler extends HandlerWrapper
|
||||||
return System.currentTimeMillis() - _statsStartedAt.get();
|
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
|
* @return the total bytes of content sent in responses
|
||||||
*/
|
*/
|
||||||
|
@ -329,21 +450,44 @@ public class StatisticsHandler extends HandlerWrapper
|
||||||
return _responsesTotalBytes.get();
|
return _responsesTotalBytes.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String toStatsHTML()
|
||||||
* @return the minimum time (in milliseconds) of request suspension
|
|
||||||
* since {@link #statsReset()} was last called.
|
|
||||||
*/
|
|
||||||
public long getSuspendedTimeMin()
|
|
||||||
{
|
{
|
||||||
return _suspendMinTime.get();
|
StringBuilder sb = new StringBuilder();
|
||||||
}
|
|
||||||
|
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.io.IOException;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.eclipse.jetty.continuation.Continuation;
|
import org.eclipse.jetty.continuation.Continuation;
|
||||||
|
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||||
import org.eclipse.jetty.continuation.ContinuationSupport;
|
import org.eclipse.jetty.continuation.ContinuationSupport;
|
||||||
import org.eclipse.jetty.server.LocalConnector;
|
import org.eclipse.jetty.server.LocalConnector;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
|
@ -59,139 +61,10 @@ public class StatisticsHandlerTest extends TestCase
|
||||||
_server.join();
|
_server.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSuspendResume() throws Exception
|
public void testRequest() throws Exception
|
||||||
{
|
{
|
||||||
final long sleep = 500;
|
final CyclicBarrier barrier[] = { new CyclicBarrier(2), new CyclicBarrier(2)};
|
||||||
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;
|
|
||||||
_statsHandler.setHandler(new AbstractHandler()
|
_statsHandler.setHandler(new AbstractHandler()
|
||||||
{
|
{
|
||||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
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);
|
request.setHandled(true);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.sleep(sleep);
|
barrier[0].await();
|
||||||
|
barrier[1].await();
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (InterruptedException x)
|
catch (Exception x)
|
||||||
{
|
{
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw (IOException)new IOException().initCause(x);
|
throw (IOException)new IOException().initCause(x);
|
||||||
|
@ -213,24 +88,452 @@ public class StatisticsHandlerTest extends TestCase
|
||||||
String request = "GET / HTTP/1.1\r\n" +
|
String request = "GET / HTTP/1.1\r\n" +
|
||||||
"Host: localhost\r\n" +
|
"Host: localhost\r\n" +
|
||||||
"\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(1, _statsHandler.getRequests());
|
||||||
assertEquals(1, _statsHandler.getResponses2xx());
|
assertEquals(0, _statsHandler.getRequestsActive());
|
||||||
assertTrue(sleep <= _statsHandler.getRequestTimeMin());
|
assertEquals(1, _statsHandler.getRequestsActiveMax());
|
||||||
assertEquals(_statsHandler.getRequestTimeMin(), _statsHandler.getRequestTimeMax());
|
|
||||||
assertEquals(_statsHandler.getRequestTimeMin(), _statsHandler.getRequestTimeTotal());
|
|
||||||
assertEquals(_statsHandler.getRequestTimeMin(), _statsHandler.getRequestTimeAverage());
|
|
||||||
|
|
||||||
_connector.getResponses(request);
|
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());
|
||||||
|
|
||||||
|
_latchHandler.reset();
|
||||||
|
barrier[0].reset();
|
||||||
|
barrier[1].reset();
|
||||||
|
|
||||||
|
_connector.executeRequest(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(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());
|
assertEquals(2, _statsHandler.getResponses2xx());
|
||||||
assertTrue(sleep <= _statsHandler.getRequestTimeMin());
|
|
||||||
assertTrue(sleep <= _statsHandler.getRequestTimeAverage());
|
_latchHandler.reset(2);
|
||||||
assertTrue(_statsHandler.getRequestTimeTotal() >= 2 * sleep);
|
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
|
* 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
|
* 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 static class LatchHandler extends HandlerWrapper
|
||||||
{
|
{
|
||||||
private volatile CountDownLatch latch = new CountDownLatch(1);
|
private volatile CountDownLatch _latch = new CountDownLatch(1);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
|
final CountDownLatch latch=_latch;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
super.handle(path, request, httpRequest, httpResponse);
|
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
|
private boolean await(long ms) throws InterruptedException
|
||||||
{
|
{
|
||||||
boolean result = latch.await(ms, TimeUnit.MILLISECONDS);
|
return _latch.await(ms, TimeUnit.MILLISECONDS);
|
||||||
latch = new CountDownLatch(1);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,17 +111,24 @@ public class StatisticsServlet extends HttpServlet
|
||||||
|
|
||||||
sb.append(" <requests>\n");
|
sb.append(" <requests>\n");
|
||||||
sb.append(" <statsOnMs>").append(_statsHandler.getStatsOnMs()).append("</statsOnMs>\n");
|
sb.append(" <statsOnMs>").append(_statsHandler.getStatsOnMs()).append("</statsOnMs>\n");
|
||||||
|
|
||||||
sb.append(" <requests>").append(_statsHandler.getRequests()).append("</requests>\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(" <requestsActive>").append(_statsHandler.getRequestsActive()).append("</requestsActive>\n");
|
||||||
sb.append(" <requestsActiveMax>").append(_statsHandler.getRequestsActiveMax()).append("</requestsActiveMax>\n");
|
sb.append(" <requestsActiveMax>").append(_statsHandler.getRequestsActiveMax()).append("</requestsActiveMax>\n");
|
||||||
sb.append(" <requestsTimeTotal>").append(_statsHandler.getRequestTimeTotal()).append("</requestsTimeTotal>\n");
|
sb.append(" <requestsTimeTotal>").append(_statsHandler.getRequestTimeTotal()).append("</requestsTimeTotal>\n");
|
||||||
sb.append(" <requestsTimeAverage>").append(_statsHandler.getRequestTimeAverage()).append("</requestsTimeAverage>\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(" <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(" </requests>\n");
|
||||||
|
|
||||||
sb.append(" <responses>\n");
|
sb.append(" <responses>\n");
|
||||||
|
@ -173,32 +180,8 @@ public class StatisticsServlet extends HttpServlet
|
||||||
|
|
||||||
private void sendTextResponse(HttpServletResponse response) throws IOException
|
private void sendTextResponse(HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(_statsHandler.toStatsHTML());
|
||||||
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("<h2>Connections:</h2>\n");
|
sb.append("<h2>Connections:</h2>\n");
|
||||||
for (Connector connector : _connectors)
|
for (Connector connector : _connectors)
|
||||||
|
|
|
@ -65,11 +65,6 @@
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
|
|
@ -52,6 +52,7 @@ public class Dump extends HttpServlet
|
||||||
{
|
{
|
||||||
static boolean fixed;
|
static boolean fixed;
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
public void init(ServletConfig config) throws ServletException
|
public void init(ServletConfig config) throws ServletException
|
||||||
{
|
{
|
||||||
super.init(config);
|
super.init(config);
|
||||||
|
@ -131,27 +132,13 @@ public class Dump extends HttpServlet
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
Continuation continuation = ContinuationSupport.getContinuation(request,response);
|
Continuation continuation = ContinuationSupport.getContinuation(request);
|
||||||
continuation.resume();
|
continuation.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
}).start();
|
}).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)
|
if (request.getParameter("complete")!=null)
|
||||||
{
|
{
|
||||||
final long complete=Long.parseLong(request.getParameter("complete"));
|
final long complete=Long.parseLong(request.getParameter("complete"));
|
||||||
|
@ -183,6 +170,21 @@ public class Dump extends HttpServlet
|
||||||
}).start();
|
}).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);
|
request.setAttribute("Dump", this);
|
||||||
getServletContext().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="dispatch">Dispatcher Servlet</a></li>
|
||||||
<li>a <a href="rewrite/">Request Rewrite 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="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>
|
<li>a <a href="auth.html">Authentication</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p/>
|
<p/>
|
||||||
|
|
Loading…
Reference in New Issue