@Override
  public CompletableFuture<Void> visitReadOnlyKeyCommand(
      InvocationContext ctx, ReadOnlyKeyCommand command) throws Throwable {
    try {
      CacheEntry entry = entryFactory.wrapEntryForReading(ctx, command.getKey(), null);
      // Null entry is often considered to mean that entry is not available
      // locally, but if there's no need to get remote, the read-only
      // function needs to be executed, so force a non-null entry in
      // context with null content
      if (entry == null && cdl.localNodeIsOwner(command.getKey())) {
        entryFactory.wrapEntryForReading(ctx, command.getKey(), NullCacheEntry.getInstance());
      }

      return ctx.shortCircuit(ctx.forkInvocationSync(command));
    } finally {
      // needed because entries might be added in L1
      if (!ctx.isInTxScope()) commitContextEntries(ctx, command, null);
      else {
        CacheEntry entry = ctx.lookupEntry(command.getKey());
        if (entry != null) {
          entry.setSkipLookup(true);
        }
      }
    }
  }
 private CompletableFuture<Void> visitDataReadCommand(
     InvocationContext ctx, AbstractDataCommand command) throws Throwable {
   try {
     entryFactory.wrapEntryForReading(ctx, command.getKey(), null);
     return ctx.shortCircuit(ctx.forkInvocationSync(command));
   } finally {
     // needed because entries might be added in L1
     if (!ctx.isInTxScope()) commitContextEntries(ctx, command, null);
     else {
       CacheEntry entry = ctx.lookupEntry(command.getKey());
       if (entry != null) {
         entry.setSkipLookup(true);
       }
     }
   }
 }
 @Override
 public CompletableFuture<Void> visitReadOnlyManyCommand(
     InvocationContext ctx, ReadOnlyManyCommand command) throws Throwable {
   try {
     for (Object key : command.getKeys()) {
       entryFactory.wrapEntryForReading(ctx, key, null);
     }
     return ctx.shortCircuit(ctx.forkInvocationSync(command));
   } finally {
     if (ctx.isInTxScope()) {
       for (Object key : command.getKeys()) {
         CacheEntry entry = ctx.lookupEntry(key);
         if (entry != null) {
           entry.setSkipLookup(true);
         }
       }
     }
   }
 }