@Override
  protected void commitContextEntry(
      CacheEntry entry,
      InvocationContext ctx,
      FlagAffectedCommand command,
      Metadata metadata,
      Flag stateTransferFlag,
      boolean l1Invalidation) {
    if (ctx.isInTxScope() && stateTransferFlag == null) {
      Metadata commitMetadata;
      // If user provided version, use it, otherwise generate/increment accordingly
      ClusteredRepeatableReadEntry clusterMvccEntry = (ClusteredRepeatableReadEntry) entry;
      EntryVersion existingVersion = clusterMvccEntry.getMetadata().version();
      EntryVersion newVersion;
      if (existingVersion == null) {
        newVersion = versionGenerator.generateNew();
      } else {
        newVersion = versionGenerator.increment((IncrementableEntryVersion) existingVersion);
      }

      if (metadata == null)
        commitMetadata = new EmbeddedMetadata.Builder().version(newVersion).build();
      else commitMetadata = metadata.builder().version(newVersion).build();

      cdl.commitEntry(entry, commitMetadata, command, ctx, null, l1Invalidation);
    } else {
      // This could be a state transfer call!
      cdl.commitEntry(entry, entry.getMetadata(), command, ctx, stateTransferFlag, l1Invalidation);
    }
  }
Ejemplo n.º 2
0
  private void raiseEventForInitialTransfer(UUID identifier, CacheEntry entry, boolean clustered) {
    EventImpl preEvent;
    if (clustered) {
      // In clustered mode we only send post event
      preEvent = null;
    } else {
      preEvent = EventImpl.createEvent(cache, CACHE_ENTRY_CREATED);
      preEvent.setKey(entry.getKey());
      preEvent.setPre(true);
    }

    EventImpl postEvent = EventImpl.createEvent(cache, CACHE_ENTRY_CREATED);
    postEvent.setKey(entry.getKey());
    postEvent.setValue(entry.getValue());
    postEvent.setMetadata(entry.getMetadata());
    postEvent.setPre(false);

    for (CacheEntryListenerInvocation<K, V> invocation : cacheEntryCreatedListeners) {
      // Now notify all our methods of the creates
      if (invocation.getIdentifier() == identifier) {
        if (preEvent != null) {
          // Non clustered notifications are done twice
          invocation.invokeNoChecks(preEvent, true, true);
        }
        invocation.invokeNoChecks(postEvent, true, true);
      }
    }
  }
Ejemplo n.º 3
0
  private void configureEvent(
      EventImpl<K, V> e,
      K key,
      V value,
      boolean pre,
      InvocationContext ctx,
      FlagAffectedCommand command,
      V previousValue,
      Metadata previousMetadata) {
    boolean originLocal = ctx.isOriginLocal();

    e.setOriginLocal(originLocal);
    e.setValue(pre ? previousValue : value);
    e.setPre(pre);
    e.setOldValue(previousValue);
    e.setOldMetadata(previousMetadata);
    CacheEntry entry = ctx.lookupEntry(key);
    if (entry != null) {
      e.setMetadata(entry.getMetadata());
    }
    Set<Flag> flags;
    if (command != null
        && (flags = command.getFlags()) != null
        && flags.contains(Flag.COMMAND_RETRY)) {
      e.setCommandRetried(true);
    }
    e.setKey(key);
    setTx(ctx, e);
  }
Ejemplo n.º 4
0
  protected Object performRemove(CacheEntry e, InvocationContext ctx) {
    final Object removedValue = e.getValue();
    notify(ctx, removedValue, e.getMetadata(), true);

    e.setRemoved(true);
    e.setValid(false);
    e.setChanged(true);

    if (valueMatcher != ValueMatcher.MATCH_EXPECTED_OR_NEW) {
      return isConditional() ? true : removedValue;
    } else {
      // Return the expected value when retrying
      return isConditional() ? true : value;
    }
  }
    @Override
    protected void commitSingleEntry(
        CacheEntry entry,
        Metadata metadata,
        FlagAffectedCommand command,
        InvocationContext ctx,
        Flag trackFlag,
        boolean l1Invalidation) {
      // Don't allow the CH to change (and state transfer to invalidate entries)
      // between the ownership check and the commit
      stateTransferLock.acquireSharedTopologyLock();
      try {
        boolean doCommit = true;
        // ignore locality for removals, even if skipOwnershipCheck is not true
        boolean skipOwnershipCheck = command != null && command.hasFlag(Flag.SKIP_OWNERSHIP_CHECK);

        boolean isForeignOwned = !skipOwnershipCheck && !localNodeIsOwner(entry.getKey());
        if (isForeignOwned && !entry.isRemoved()) {
          if (configuration.clustering().l1().enabled()) {
            // transform for L1
            long lifespan;
            if (metadata != null) {
              lifespan = metadata.lifespan();
            } else {
              lifespan = entry.getLifespan();
            }
            if (lifespan < 0 || lifespan > configuration.clustering().l1().lifespan()) {
              Metadata.Builder builder;
              if (metadata != null) {
                builder = metadata.builder();
              } else {
                builder = entry.getMetadata().builder();
              }
              metadata = builder.lifespan(configuration.clustering().l1().lifespan()).build();
            }
          } else {
            doCommit = false;
          }
        }

        boolean created = false;
        boolean removed = false;
        boolean expired = false;
        if (!isForeignOwned) {
          created = entry.isCreated();
          removed = entry.isRemoved();
          if (removed && entry instanceof MVCCEntry) {
            expired = ((MVCCEntry) entry).isExpired();
          }
        }

        if (doCommit) {
          InternalCacheEntry previousEntry = dataContainer.peek(entry.getKey());
          Object previousValue = null;
          Metadata previousMetadata = null;
          if (previousEntry != null) {
            previousValue = previousEntry.getValue();
            previousMetadata = previousEntry.getMetadata();
          }
          commitManager.commit(entry, metadata, trackFlag, l1Invalidation);
          if (!isForeignOwned) {
            notifyCommitEntry(
                created, removed, expired, entry, ctx, command, previousValue, previousMetadata);
          }
        } else entry.rollback();

      } finally {
        stateTransferLock.releaseSharedTopologyLock();
      }
    }
    protected void notifyCommitEntry(
        boolean created,
        boolean removed,
        boolean expired,
        CacheEntry entry,
        InvocationContext ctx,
        FlagAffectedCommand command,
        Object previousValue,
        Metadata previousMetadata) {
      boolean isWriteOnly =
          (command instanceof WriteCommand) && ((WriteCommand) command).isWriteOnly();
      if (removed) {
        if (command instanceof RemoveCommand) {
          ((RemoveCommand) command).notify(ctx, previousValue, previousMetadata, false);
        } else {
          if (expired) {
            notifier.notifyCacheEntryExpired(entry.getKey(), previousValue, previousMetadata, ctx);
          } else {
            notifier.notifyCacheEntryRemoved(
                entry.getKey(), previousValue, previousMetadata, false, ctx, command);
          }

          // A write-only command only writes and so can't 100% guarantee
          // to be able to retrieve previous value when removed, so only
          // send remove event when the command is read-write.
          if (!isWriteOnly)
            functionalNotifier.notifyOnRemove(
                EntryViews.readOnly(entry.getKey(), previousValue, previousMetadata));

          functionalNotifier.notifyOnWrite(() -> EntryViews.noValue(entry.getKey()));
        }
      } else {
        // Notify entry event after container has been updated
        if (created) {
          notifier.notifyCacheEntryCreated(
              entry.getKey(), entry.getValue(), entry.getMetadata(), false, ctx, command);

          // A write-only command only writes and so can't 100% guarantee
          // that an entry has been created, so only send create event
          // when the command is read-write.
          if (!isWriteOnly) functionalNotifier.notifyOnCreate(EntryViews.readOnly(entry));

          functionalNotifier.notifyOnWrite(() -> EntryViews.readOnly(entry));
        } else {
          notifier.notifyCacheEntryModified(
              entry.getKey(),
              entry.getValue(),
              entry.getMetadata(),
              previousValue,
              previousMetadata,
              false,
              ctx,
              command);

          // A write-only command only writes and so can't 100% guarantee
          // that an entry has been created, so only send modify when the
          // command is read-write.
          if (!isWriteOnly)
            functionalNotifier.notifyOnModify(
                EntryViews.readOnly(entry.getKey(), previousValue, previousMetadata),
                EntryViews.readOnly(entry));

          functionalNotifier.notifyOnWrite(() -> EntryViews.readOnly(entry));
        }
      }
    }