@QueueCallback(QueueCallbackType.LIMIT)
  private void queueLimit() {

    if (messageCountSinceLastFlush > 100_000) {

      now = Timer.timer().now();
      logger.debug(
          "EventManager {}: Sending all " + "messages because we have more than 100K", name);
      sendMessages();
      return;
    }

    now = Timer.timer().now();
    long duration = now - lastFlushTime;

    if (duration > 50 && messageCountSinceLastFlush > 0) {
      if (debug) {
        logger.debug(
            "EventManager {}: Sending all "
                + "messages because 50 MS elapsed and we have more than 0",
            name);
      }
      sendMessages();
    }

    eventBus.flush();
  }
  private void sendMessages() {

    flushCount++;
    lastFlushTime = now;

    stats.recordCount(eventCountStatsKey, messageCountSinceLastFlush);
    messageCountSinceLastFlush = 0;

    if (debug) {
      logger.debug("EventManager {} flushCount {}", name, flushCount);
    }

    final Set<Map.Entry<String, List<Object>>> entries = eventMap.entrySet();
    for (Map.Entry<String, List<Object>> entry : entries) {
      String channelName = entry.getKey();
      final List<Object> events = entry.getValue();
      for (Object event : events) {
        eventBus.send(channelName, event);
      }
      events.clear();
    }

    //noinspection Convert2streamapi
    for (SendQueue<Event<Object>> sendQueue : queuesToFlush) {
      sendQueue.flushSends();
    }
  }
  @QueueCallback(QueueCallbackType.IDLE)
  private void queueIdle() {

    now = Timer.timer().now();

    if (messageCountSinceLastFlush > 0) {

      sendMessages();
      return;
    }

    eventBus.flush();
  }
  @QueueCallback(QueueCallbackType.EMPTY)
  private void queueEmpty() {

    if (messageCountSinceLastFlush > 100) {

      now = Timer.timer().now();
      sendMessages();
      return;
    }

    now = Timer.timer().now();
    long duration = now - lastFlushTime;

    if (duration > 20 && messageCountSinceLastFlush > 0) {
      sendMessages();
    }

    eventBus.flush();
  }
  @SuppressWarnings("Convert2Lambda")
  @Override
  public void subscribe(final String channelName, final SendQueue<Event<Object>> sendQueue) {

    logger.info(
        "EventManager {}::subscribe() channel name {} sendQueue {}",
        name,
        channelName,
        sendQueue.name());
    queuesToFlush.add(sendQueue);

    //noinspection Anonymous2MethodRef
    eventBus.register(
        channelName,
        new EventSubscriber<Object>() {
          @Override
          public void listen(Event<Object> event) {
            sendQueue.send(event);
          }
        });
  }
 @Override
 public void forwardEvent(final EventTransferObject<Object> event) {
   messageCountSinceLastFlush++;
   eventBus.forwardEvent(event);
 }
 @Override
 public <T> void unregister(String channelName, EventListener<T> listener) {
   eventBus.unregister(channelName, listener);
 }