Merge pull request #5517 from eclipse/jetty-10.0.x-5493-StatisticsHandler

Issue #5493 - Fix and simplify graceful shutdown of StatisticsHandler
This commit is contained in:
Lachlan 2020-10-29 08:55:22 +11:00 committed by GitHub
commit 5bb47c954c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 44 deletions

View File

@ -48,7 +48,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
{ {
private static final Logger LOG = LoggerFactory.getLogger(StatisticsHandler.class); private static final Logger LOG = LoggerFactory.getLogger(StatisticsHandler.class);
private final AtomicLong _statsStartedAt = new AtomicLong(); private final AtomicLong _statsStartedAt = new AtomicLong();
private volatile Shutdown _shutdown; private final Shutdown _shutdown;
private final CounterStatistic _requestStats = new CounterStatistic(); private final CounterStatistic _requestStats = new CounterStatistic();
private final SampleStatistic _requestTimeStats = new SampleStatistic(); private final SampleStatistic _requestTimeStats = new SampleStatistic();
@ -92,27 +92,33 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
@Override @Override
public void onComplete(AsyncEvent event) public void onComplete(AsyncEvent event)
{ {
HttpChannelState state = ((AsyncContextEvent)event).getHttpChannelState(); Request request = ((AsyncContextEvent)event).getHttpChannelState().getBaseRequest();
long elapsed = System.currentTimeMillis() - request.getTimeStamp();
Request request = state.getBaseRequest(); _requestStats.decrement();
final long elapsed = System.currentTimeMillis() - request.getTimeStamp();
long numRequests = _requestStats.decrement();
_requestTimeStats.record(elapsed); _requestTimeStats.record(elapsed);
updateResponse(request); updateResponse(request);
_asyncWaitStats.decrement(); _asyncWaitStats.decrement();
if (numRequests == 0 && _gracefulShutdownWaitsForRequests) if (_shutdown.isShutdown())
{ _shutdown.check();
Shutdown shutdown = _shutdown;
if (shutdown != null)
shutdown.check();
}
} }
}; };
public StatisticsHandler()
{
_shutdown = new Shutdown(this)
{
@Override
public boolean isShutdownDone()
{
if (_gracefulShutdownWaitsForRequests)
return _requestStats.getCurrent() == 0;
else
return _dispatchedStats.getCurrent() == 0;
}
};
}
/** /**
* Resets the current request statistics. * Resets the current request statistics.
*/ */
@ -174,8 +180,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
final long dispatched = now - start; final long dispatched = now - start;
long numRequests = -1; _dispatchedStats.decrement();
long numDispatches = _dispatchedStats.decrement();
_dispatchedTimeStats.record(dispatched); _dispatchedTimeStats.record(dispatched);
if (state.isInitial()) if (state.isInitial())
@ -187,19 +192,14 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
} }
else else
{ {
numRequests = _requestStats.decrement(); _requestStats.decrement();
_requestTimeStats.record(dispatched); _requestTimeStats.record(dispatched);
updateResponse(baseRequest); updateResponse(baseRequest);
} }
} }
Shutdown shutdown = _shutdown; if (_shutdown.isShutdown())
if (shutdown != null) _shutdown.check();
{
response.flushBuffer();
if (_gracefulShutdownWaitsForRequests ? (numRequests == 0) : (numDispatches == 0))
shutdown.check();
}
} }
} }
@ -230,8 +230,11 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
} }
} }
else else
{
// will fall through to not found handler // will fall through to not found handler
_responses4xx.increment(); _responses4xx.increment();
}
_responsesTotalBytes.add(response.getContentCount()); _responsesTotalBytes.add(response.getContentCount());
} }
@ -240,17 +243,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
{ {
if (getHandler() == null) if (getHandler() == null)
throw new IllegalStateException("StatisticsHandler has no Wrapped Handler"); throw new IllegalStateException("StatisticsHandler has no Wrapped Handler");
_shutdown = new Shutdown(this) _shutdown.cancel();
{
@Override
public boolean isShutdownDone()
{
if (_gracefulShutdownWaitsForRequests)
return _requestStats.getCurrent() == 0;
else
return _dispatchedStats.getCurrent() == 0;
}
};
super.doStart(); super.doStart();
statsReset(); statsReset();
} }
@ -258,8 +251,8 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
@Override @Override
protected void doStop() throws Exception protected void doStop() throws Exception
{ {
_shutdown.cancel();
super.doStop(); super.doStop();
_shutdown = null;
} }
/** /**
@ -610,17 +603,13 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
@Override @Override
public CompletableFuture<Void> shutdown() public CompletableFuture<Void> shutdown()
{ {
Shutdown shutdown = _shutdown; return _shutdown.shutdown();
if (shutdown == null)
return CompletableFuture.completedFuture(null);
return shutdown.shutdown();
} }
@Override @Override
public boolean isShutdown() public boolean isShutdown()
{ {
Shutdown shutdown = _shutdown; return _shutdown.isShutdown();
return shutdown == null || shutdown.isShutdown();
} }
@Override @Override

View File

@ -78,7 +78,8 @@ public interface Graceful
public CompletableFuture<Void> shutdown() public CompletableFuture<Void> shutdown()
{ {
if (_done.get() == null) if (_done.get() == null)
_done.compareAndSet(null, new CompletableFuture<Void>() {
_done.compareAndSet(null, new CompletableFuture<>()
{ {
@Override @Override
public String toString() public String toString()
@ -86,6 +87,7 @@ public interface Graceful
return String.format("Shutdown<%s>@%x", _component, hashCode()); return String.format("Shutdown<%s>@%x", _component, hashCode());
} }
}); });
}
CompletableFuture<Void> done = _done.get(); CompletableFuture<Void> done = _done.get();
check(); check();
return done; return done;
@ -110,6 +112,15 @@ public interface Graceful
done.complete(null); done.complete(null);
} }
public void cancel()
{
CompletableFuture<Void> done = _done.get();
if (done != null && !done.isDone())
done.cancel(true);
_done.set(null);
}
/** /**
* @return True if the component is shutdown and has no remaining load. * @return True if the component is shutdown and has no remaining load.
*/ */