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; }
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); }