@Override
    public Map<String, Number> call() throws Exception {

      Map<String, Number> map = new HashMap<>();
      Stats stats = remoteCache.getStats();
      map.put(AVERAGE_READ_TIME, stats.getAverageReadTime());
      map.put(AVERAGE_WRITE_TIME, stats.getAverageWriteTime());
      map.put(AVERAGE_REMOVE_TIME, stats.getAverageRemoveTime());
      map.put(EVICTIONS, stats.getEvictions());
      map.put(HITS, stats.getHits());
      map.put(MISSES, stats.getMisses());
      final CacheMode cacheMode = getCacheMode(remoteCache);
      // for replicated caches, we don't need to send the number of entries since it is the same in
      // all the nodes.
      if (cacheMode.isDistributed()) {
        map.put(NUMBER_OF_ENTRIES, stats.getCurrentNumberOfEntries() / numOwners());
      } else if (!cacheMode.isReplicated()) {
        map.put(NUMBER_OF_ENTRIES, stats.getCurrentNumberOfEntries());
      }
      map.put(STORES, stats.getStores());
      map.put(REMOVE_HITS, stats.getRemoveHits());
      map.put(REMOVE_MISSES, stats.getRemoveMisses());
      map.put(TIME_SINCE_START, stats.getTimeSinceStart());

      LockManager lockManager = remoteCache.getLockManager();
      map.put(NUMBER_OF_LOCKS_HELD, lockManager.getNumberOfLocksHeld());

      // number of locks available is not exposed through the LockManager interface
      map.put(NUMBER_OF_LOCKS_AVAILABLE, 0);

      // invalidations
      InvalidationInterceptor invalidationInterceptor =
          getFirstInterceptorWhichExtends(remoteCache, InvalidationInterceptor.class);
      if (invalidationInterceptor != null) {
        map.put(INVALIDATIONS, invalidationInterceptor.getInvalidations());
      } else {
        map.put(INVALIDATIONS, 0);
      }

      // passivations
      PassivationManager pManager =
          remoteCache.getComponentRegistry().getComponent(PassivationManager.class);
      if (pManager != null) {
        map.put(PASSIVATIONS, pManager.getPassivations());
      } else {
        map.put(PASSIVATIONS, 0);
      }

      // activations
      ActivationManager aManager =
          remoteCache.getComponentRegistry().getComponent(ActivationManager.class);
      if (pManager != null) {
        map.put(ACTIVATIONS, aManager.getActivationCount());
      } else {
        map.put(ACTIVATIONS, 0);
      }

      // cache loaders
      ActivationInterceptor aInterceptor =
          getFirstInterceptorWhichExtends(remoteCache, ActivationInterceptor.class);
      if (aInterceptor != null) {
        map.put(CACHE_LOADER_LOADS, aInterceptor.getCacheLoaderLoads());
        map.put(CACHE_LOADER_MISSES, aInterceptor.getCacheLoaderMisses());
      } else {
        map.put(CACHE_LOADER_LOADS, 0);
        map.put(CACHE_LOADER_MISSES, 0);
      }
      // cache store
      CacheWriterInterceptor interceptor =
          getFirstInterceptorWhichExtends(remoteCache, CacheWriterInterceptor.class);
      if (interceptor != null) {
        map.put(CACHE_WRITER_STORES, interceptor.getWritesToTheStores());
      } else {
        map.put(CACHE_WRITER_STORES, 0);
      }
      return map;
    }
예제 #2
0
  /**
   * Adds the listener using the provided filter converter and class loader. The provided builder is
   * used to add additional configuration including (clustered, onlyPrimary & identifier) which can
   * be used after this method is completed to see what values were used in the addition of this
   * listener
   *
   * @param listener
   * @param filter
   * @param converter
   * @param classLoader
   * @param <C>
   * @return
   */
  public <C> void addListener(
      Object listener,
      CacheEventFilter<? super K, ? super V> filter,
      CacheEventConverter<? super K, ? super V, C> converter,
      ClassLoader classLoader) {
    Listener l = testListenerClassValidity(listener.getClass());
    UUID generatedId = UUID.randomUUID();
    CacheMode cacheMode = config.clustering().cacheMode();
    CacheInvocationBuilder builder = new CacheInvocationBuilder();
    builder
        .setIncludeCurrentState(l.includeCurrentState())
        .setClustered(l.clustered())
        .setOnlyPrimary(
            l.clustered() ? (cacheMode.isDistributed() ? true : false) : l.primaryOnly())
        .setFilter(filter)
        .setConverter(converter)
        .setIdentifier(generatedId)
        .setClassLoader(classLoader);
    boolean foundMethods = validateAndAddListenerInvocation(listener, builder);

    if (foundMethods && l.clustered()) {
      if (cacheMode.isInvalidation()) {
        throw new UnsupportedOperationException(
            "Cluster listeners cannot be used with Invalidation Caches!");
      } else if (cacheMode.isDistributed()) {
        clusterListenerIDs.put(listener, generatedId);
        EmbeddedCacheManager manager = cache.getCacheManager();
        Address ourAddress = manager.getAddress();

        List<Address> members = manager.getMembers();
        // If we are the only member don't even worry about sending listeners
        if (members != null && members.size() > 1) {
          DistributedExecutionCompletionService decs =
              new DistributedExecutionCompletionService(distExecutorService);

          if (log.isTraceEnabled()) {
            log.tracef(
                "Replicating cluster listener to other nodes %s for cluster listener with id %s",
                members, generatedId);
          }
          Callable callable =
              new ClusterListenerReplicateCallable(
                  generatedId, ourAddress, filter, converter, l.sync());
          for (Address member : members) {
            if (!member.equals(ourAddress)) {
              decs.submit(member, callable);
            }
          }

          for (int i = 0; i < members.size() - 1; ++i) {
            try {
              decs.take().get();
            } catch (InterruptedException e) {
              throw new CacheListenerException(e);
            } catch (ExecutionException e) {
              throw new CacheListenerException(e);
            }
          }

          int extraCount = 0;
          // If anyone else joined since we sent these we have to send the listeners again, since
          // they may have queried
          // before the other nodes got the new listener
          List<Address> membersAfter = manager.getMembers();
          for (Address member : membersAfter) {
            if (!members.contains(member) && !member.equals(ourAddress)) {
              if (log.isTraceEnabled()) {
                log.tracef(
                    "Found additional node %s that joined during replication of cluster listener with id %s",
                    member, generatedId);
              }
              extraCount++;
              decs.submit(member, callable);
            }
          }

          for (int i = 0; i < extraCount; ++i) {
            try {
              decs.take().get();
            } catch (InterruptedException e) {
              throw new CacheListenerException(e);
            } catch (ExecutionException e) {
              throw new CacheListenerException(e);
            }
          }
        }
      }
    }

    // If we have a segment listener handler, it means we have to do initial state
    QueueingSegmentListener handler = segmentHandler.remove(generatedId);
    if (handler != null) {
      if (log.isTraceEnabled()) {
        log.tracef("Listener %s requests initial state for cache", generatedId);
      }
      try (CloseableIterator<CacheEntry<K, C>> iterator =
          entryRetriever.retrieveEntries(
              filter == null ? null : new CacheEventFilterAsKeyValueFilter(filter),
              converter == null ? null : new CacheEventConverterAsConverter(converter),
              null,
              handler)) {
        while (iterator.hasNext()) {
          CacheEntry<K, C> entry = iterator.next();
          // Mark the key as processed and see if we had a concurrent update
          Object value = handler.markKeyAsProcessing(entry.getKey());
          if (value == BaseQueueingSegmentListener.REMOVED) {
            // Don't process this value if we had a concurrent remove
            continue;
          }
          raiseEventForInitialTransfer(generatedId, entry, builder.isClustered());

          handler.notifiedKey(entry.getKey());
        }
      }

      Set<CacheEntry> entries = handler.findCreatedEntries();

      for (CacheEntry entry : entries) {
        raiseEventForInitialTransfer(generatedId, entry, builder.isClustered());
      }

      if (log.isTraceEnabled()) {
        log.tracef("Listener %s initial state for cache completed", generatedId);
      }

      handler.transferComplete();
    }
  }