/** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Override
  public boolean addAll(final Collection<? extends T> items) {
    A.notNull(items, "items");

    try {
      boolean retVal;

      int cnt = 0;

      while (true) {
        try (IgniteInternalTx tx = cache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) {
          Long idx = (Long) cache.invoke(queueKey, new AddProcessor(id, items.size())).get();

          if (idx != null) {
            checkRemoved(idx);

            Map<GridCacheQueueItemKey, T> putMap = new HashMap<>();

            for (T item : items) {
              putMap.put(itemKey(idx), item);

              idx++;
            }

            cache.putAll(putMap);

            retVal = true;
          } else retVal = false;

          tx.commit();

          break;
        } catch (ClusterTopologyCheckedException e) {
          if (e instanceof ClusterGroupEmptyCheckedException) throw e;

          if (cnt++ == MAX_UPDATE_RETRIES) throw e;
          else {
            U.warn(log, "Failed to add item, will retry [err=" + e + ']');

            U.sleep(RETRY_DELAY);
          }
        }
      }

      return retVal;
    } catch (IgniteCheckedException e) {
      throw U.convertException(e);
    }
  }
  /** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Override
  public boolean offer(final T item) throws IgniteException {
    A.notNull(item, "item");

    try {
      boolean retVal;

      int cnt = 0;

      while (true) {
        try {
          try (IgniteInternalTx tx = cache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) {
            Long idx = (Long) cache.invoke(queueKey, new AddProcessor(id, 1)).get();

            if (idx != null) {
              checkRemoved(idx);

              cache.getAndPut(itemKey(idx), item);

              retVal = true;
            } else retVal = false;

            tx.commit();

            break;
          }
        } catch (ClusterTopologyCheckedException e) {
          if (e instanceof ClusterGroupEmptyCheckedException) throw e;

          if (cnt++ == MAX_UPDATE_RETRIES) throw e;
          else {
            U.warn(log, "Failed to add item, will retry [err=" + e + ']');

            U.sleep(RETRY_DELAY);
          }
        }
      }

      return retVal;
    } catch (IgniteCheckedException e) {
      throw U.convertException(e);
    }
  }
  /** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Nullable
  @Override
  public T poll() throws IgniteException {
    try {
      int cnt = 0;

      T retVal;

      while (true) {
        try (IgniteInternalTx tx = cache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) {
          Long idx = (Long) cache.invoke(queueKey, new PollProcessor(id)).get();

          if (idx != null) {
            checkRemoved(idx);

            retVal = (T) cache.getAndRemove(itemKey(idx));

            assert retVal != null : idx;
          } else retVal = null;

          tx.commit();

          break;
        } catch (ClusterTopologyCheckedException e) {
          if (e instanceof ClusterGroupEmptyCheckedException) throw e;

          if (cnt++ == MAX_UPDATE_RETRIES) throw e;
          else {
            U.warn(log, "Failed to add item, will retry [err=" + e + ']');

            U.sleep(RETRY_DELAY);
          }
        }
      }

      return retVal;
    } catch (IgniteCheckedException e) {
      throw U.convertException(e);
    }
  }
  /** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Override
  protected void removeItem(final long rmvIdx) throws IgniteCheckedException {
    try {
      int cnt = 0;

      while (true) {
        try (IgniteInternalTx tx = cache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) {
          Long idx = (Long) cache.invoke(queueKey, new RemoveProcessor(id, rmvIdx)).get();

          if (idx != null) {
            checkRemoved(idx);

            boolean rmv = cache.remove(itemKey(idx));

            assert rmv : idx;
          }

          tx.commit();

          break;
        } catch (ClusterTopologyCheckedException e) {
          if (e instanceof ClusterGroupEmptyCheckedException) throw e;

          if (cnt++ == MAX_UPDATE_RETRIES) throw e;
          else {
            U.warn(log, "Failed to add item, will retry [err=" + e + ']');

            U.sleep(RETRY_DELAY);
          }
        }
      }
    } catch (IgniteCheckedException e) {
      throw U.convertException(e);
    }
  }