@Override
  public void handle(
      String path,
      Request request,
      HttpServletRequest httpRequest,
      HttpServletResponse httpResponse)
      throws IOException, ServletException {

    activeDispatches.inc();

    final long start;
    final HttpChannelState state = request.getHttpChannelState();
    if (state.isInitial()) {
      // new request
      activeRequests.inc();
      start = request.getTimeStamp();
    } else {
      // resumed request
      start = System.currentTimeMillis();
      activeSuspended.dec();
      if (state.getState() == State.DISPATCHED) {
        asyncDispatches.mark();
      }
    }

    try {
      super.handle(path, request, httpRequest, httpResponse);
    } finally {
      final long now = System.currentTimeMillis();
      final long dispatched = now - start;

      activeDispatches.dec();
      dispatches.update(dispatched, TimeUnit.MILLISECONDS);

      if (state.isSuspended()) {
        if (state.isInitial()) {
          state.addListener(listener);
        }
        activeSuspended.inc();
      } else if (state.isInitial()) {
        requests.update(dispatched, TimeUnit.MILLISECONDS);
        updateResponses(request);
      }
      // else onCompletion will handle it.
    }
  }