<T> void completeOperation(FutureResult<T> futureResult, Callback<T> callback, T operationResult, Exception exception,
      boolean decrementOperationsCount) {
    if (decrementOperationsCount) {
      currentOperationsCount.decrementAndGet();
    }
    try {
      if (futureResult != null) {
        futureResult.done(operationResult, exception);
      }
      if (callback != null) {
        callback.onCompletion(operationResult, exception);
      }
    } catch (Exception e) {
      logger.error("Exception caught during future and callback completion", e);
    }
  }
Completes a router operation by invoking the {@code callback} and setting the {@code futureResult} with
{@code operationResult} (if any) and {@code exception} (if any).
@param <T> the type of the operation result, which depends on the kind of operation.
@param futureResult the {@link FutureResult} that needs to be set. Can be null.
@param callback that {@link Callback} that needs to be invoked. Can be null.
@param operationResult the result of the operation (if any).
@param exception {@link Exception} encountered while performing the operation (if any).
@param decrementOperationsCount if {@code true}, decrements current outstanding operations count.
ambry-router/src/main/java/com/github/ambry/router/NonBlockingRouter.java