private Map<Object, InternalCacheValue> applyStateMap(
      Map<Object, InternalCacheValue> state, boolean withRetry) {
    Map<Object, InternalCacheValue> retry =
        withRetry ? new HashMap<Object, InternalCacheValue>() : null;

    for (Map.Entry<Object, InternalCacheValue> e : state.entrySet()) {
      InternalCacheValue v = e.getValue();
      InvocationContext ctx = icc.createInvocationContext();
      // locking not necessary in the case of a join since the node isn't doing anything else
      // TODO what if the node is already running?
      ctx.setFlags(
          CACHE_MODE_LOCAL,
          SKIP_CACHE_LOAD,
          SKIP_REMOTE_LOOKUP,
          SKIP_SHARED_CACHE_STORE,
          SKIP_LOCKING,
          SKIP_OWNERSHIP_CHECK);
      try {
        PutKeyValueCommand put =
            cf.buildPutKeyValueCommand(
                e.getKey(), v.getValue(), v.getLifespan(), v.getMaxIdle(), ctx.getFlags());
        interceptorChain.invoke(ctx, put);
      } catch (Exception ee) {
        if (withRetry) {
          if (trace)
            log.tracef(
                "Problem %s encountered when applying state for key %s. Adding entry to retry queue.",
                ee.getMessage(), e.getKey());
          retry.put(e.getKey(), e.getValue());
        } else {
          log.problemApplyingStateForKey(ee.getMessage(), e.getKey());
        }
      }
    }
    return retry;
  }
예제 #2
0
  private void doApplyState(
      Address sender, int segmentId, Collection<InternalCacheEntry> cacheEntries) {
    log.debugf(
        "Applying new state for segment %d of cache %s from node %s: received %d cache entries",
        segmentId, cacheName, sender, cacheEntries.size());
    if (trace) {
      List<Object> keys = new ArrayList<Object>(cacheEntries.size());
      for (InternalCacheEntry e : cacheEntries) {
        keys.add(e.getKey());
      }
      log.tracef(
          "Received keys %s for segment %d of cache %s from node %s",
          keys, segmentId, cacheName, sender);
    }

    // CACHE_MODE_LOCAL avoids handling by StateTransferInterceptor and any potential locks in
    // StateTransferLock
    EnumSet<Flag> flags =
        EnumSet.of(
            PUT_FOR_STATE_TRANSFER,
            CACHE_MODE_LOCAL,
            IGNORE_RETURN_VALUES,
            SKIP_REMOTE_LOOKUP,
            SKIP_SHARED_CACHE_STORE,
            SKIP_OWNERSHIP_CHECK,
            SKIP_XSITE_BACKUP);
    for (InternalCacheEntry e : cacheEntries) {
      try {
        InvocationContext ctx;
        if (transactionManager != null) {
          // cache is transactional
          transactionManager.begin();
          Transaction transaction = transactionManager.getTransaction();
          ctx = icc.createInvocationContext(transaction);
          ((TxInvocationContext) ctx).setImplicitTransaction(true);
        } else {
          // non-tx cache
          ctx = icc.createSingleKeyNonTxInvocationContext();
        }

        PutKeyValueCommand put =
            useVersionedPut
                ? commandsFactory.buildVersionedPutKeyValueCommand(
                    e.getKey(),
                    e.getValue(),
                    e.getLifespan(),
                    e.getMaxIdle(),
                    e.getVersion(),
                    flags)
                : commandsFactory.buildPutKeyValueCommand(
                    e.getKey(), e.getValue(), e.getLifespan(), e.getMaxIdle(), flags);

        boolean success = false;
        try {
          interceptorChain.invoke(ctx, put);
          success = true;
        } finally {
          if (ctx.isInTxScope()) {
            if (success) {
              ((LocalTransaction) ((TxInvocationContext) ctx).getCacheTransaction())
                  .setFromStateTransfer(true);
              try {
                transactionManager.commit();
              } catch (Throwable ex) {
                log.errorf(
                    ex,
                    "Could not commit transaction created by state transfer of key %s",
                    e.getKey());
                if (transactionManager.getTransaction() != null) {
                  transactionManager.rollback();
                }
              }
            } else {
              transactionManager.rollback();
            }
          }
        }
      } catch (Exception ex) {
        log.problemApplyingStateForKey(ex.getMessage(), e.getKey(), ex);
      }
    }
    log.debugf("Finished applying state for segment %d of cache %s", segmentId, cacheName);
  }