Exemple #1
0
 @SuppressWarnings("unchecked")
 public void dispatchEvent(EventData eventData, EntryListener listener) {
   Member member = nodeEngine.getClusterService().getMember(eventData.getCaller());
   EntryEvent event =
       new DataAwareEntryEvent(
           member,
           eventData.getEventType(),
           eventData.getMapName(),
           eventData.getDataKey(),
           eventData.getDataNewValue(),
           eventData.getDataOldValue(),
           getSerializationService());
   switch (event.getEventType()) {
     case ADDED:
       listener.entryAdded(event);
       break;
     case EVICTED:
       listener.entryEvicted(event);
       break;
     case UPDATED:
       listener.entryUpdated(event);
       break;
     case REMOVED:
       listener.entryRemoved(event);
       break;
     default:
       throw new IllegalArgumentException("Invalid event type: " + event.getEventType());
   }
   MapContainer mapContainer = getMapContainer(eventData.getMapName());
   if (mapContainer.getMapConfig().isStatisticsEnabled()) {
     getLocalMapStatsImpl(eventData.getMapName()).incrementReceivedEvents();
   }
 }
Exemple #2
0
  public void connectionRemoved(Connection connection) {
    if (connection.isClient() && connection instanceof TcpIpConnection && nodeEngine.isActive()) {
      final ClientEndpoint endpoint = endpoints.get(connection);
      if (endpoint != null
          && node.getLocalMember().getUuid().equals(endpoint.getPrincipal().getOwnerUuid())) {
        removeEndpoint(connection, true);
        if (!endpoint.isFirstConnection()) {
          return;
        }
        NodeEngine nodeEngine = node.nodeEngine;
        final Collection<MemberImpl> memberList = nodeEngine.getClusterService().getMemberList();
        for (MemberImpl member : memberList) {
          final ClientDisconnectionOperation op =
              new ClientDisconnectionOperation(endpoint.getUuid());
          op.setNodeEngine(nodeEngine)
              .setServiceName(SERVICE_NAME)
              .setService(this)
              .setResponseHandler(ResponseHandlerFactory.createEmptyResponseHandler());

          if (member.localMember()) {
            nodeEngine.getOperationService().runOperation(op);
          } else {
            nodeEngine.getOperationService().send(op, member.getAddress());
          }
        }
      }
    }
  }
Exemple #3
0
 public void invalidateAllNearCaches(String mapName, Set<Data> keys) {
   if (!isNearCacheEnabled(mapName)) {
     return;
   }
   if (keys == null || keys.isEmpty()) {
     return;
   }
   // send operation.
   Operation operation =
       new NearCacheKeySetInvalidationOperation(mapName, keys).setServiceName(SERVICE_NAME);
   Collection<MemberImpl> members = nodeEngine.getClusterService().getMemberList();
   for (MemberImpl member : members) {
     try {
       if (member.localMember()) continue;
       nodeEngine.getOperationService().send(operation, member.getAddress());
     } catch (Throwable throwable) {
       logger.warning(throwable);
     }
   }
   // below local invalidation is for the case the data is cached before partition is
   // owned/migrated
   for (final Data key : keys) {
     invalidateNearCache(mapName, key);
   }
 }
Exemple #4
0
  public Runnable prepareMergeRunnable() {
    Map<MapContainer, Collection<Record>> recordMap =
        new HashMap<MapContainer, Collection<Record>>(mapContainers.size());
    InternalPartitionService partitionService = nodeEngine.getPartitionService();
    int partitionCount = partitionService.getPartitionCount();
    Address thisAddress = nodeEngine.getClusterService().getThisAddress();

    for (MapContainer mapContainer : mapContainers.values()) {
      for (int i = 0; i < partitionCount; i++) {
        RecordStore recordStore = getPartitionContainer(i).getRecordStore(mapContainer.getName());
        // add your owned entries to the map so they will be merged
        if (thisAddress.equals(partitionService.getPartitionOwner(i))) {
          Collection<Record> records = recordMap.get(mapContainer);
          if (records == null) {
            records = new ArrayList<Record>();
            recordMap.put(mapContainer, records);
          }
          records.addAll(recordStore.getReadonlyRecordMap().values());
        }
        // clear all records either owned or backup
        recordStore.reset();
      }
    }
    return new Merger(recordMap);
  }
Exemple #5
0
 public void invalidateAllNearCaches(String mapName, Data key) {
   if (!isNearCacheEnabled(mapName)) {
     return;
   }
   Collection<MemberImpl> members = nodeEngine.getClusterService().getMemberList();
   for (MemberImpl member : members) {
     try {
       if (member.localMember()) continue;
       Operation operation =
           new InvalidateNearCacheOperation(mapName, key).setServiceName(SERVICE_NAME);
       nodeEngine.getOperationService().send(operation, member.getAddress());
     } catch (Throwable throwable) {
       throw new HazelcastException(throwable);
     }
   }
   // below local invalidation is for the case the data is cached before partition is
   // owned/migrated
   invalidateNearCache(mapName, key);
 }
  public void run() {
    final NodeEngine nodeEngine = getNodeEngine();
    final Address masterAddress = nodeEngine.getMasterAddress();
    if (!masterAddress.equals(migrationInfo.getMaster())) {
      throw new RetryableHazelcastException(
          "Migration initiator is not master node! => " + toString());
    }
    if (!masterAddress.equals(getCallerAddress())) {
      throw new RetryableHazelcastException("Caller is not master node! => " + toString());
    }

    final Address source = migrationInfo.getSource();
    final Address destination = migrationInfo.getDestination();
    final Member target = nodeEngine.getClusterService().getMember(destination);
    if (target == null) {
      throw new RetryableHazelcastException(
          "Destination of migration could not be found! => " + toString());
    }
    if (destination.equals(source)) {
      getLogger().warning("Source and destination addresses are the same! => " + toString());
      success = false;
      return;
    }

    if (source == null || !source.equals(nodeEngine.getThisAddress())) {
      throw new RetryableHazelcastException(
          "Source of migration is not this node! => " + toString());
    }
    if (migrationInfo.startProcessing()) {
      try {
        PartitionServiceImpl partitionService = getService();
        PartitionImpl partition = partitionService.getPartition(migrationInfo.getPartitionId());
        final Address owner = partition.getOwner();
        if (!source.equals(owner)) {
          throw new HazelcastException(
              "Cannot migrate! This node is not owner of the partition => "
                  + migrationInfo
                  + " -> "
                  + partition);
        }
        partitionService.addActiveMigration(migrationInfo);
        final long[] replicaVersions =
            partitionService.getPartitionReplicaVersions(migrationInfo.getPartitionId());
        final long timeout = nodeEngine.getGroupProperties().PARTITION_MIGRATION_TIMEOUT.getLong();
        final Collection<Operation> tasks = prepareMigrationTasks();
        if (tasks.size() > 0) {
          returnResponse = false;
          final ResponseHandler responseHandler = getResponseHandler();
          final SerializationService serializationService = nodeEngine.getSerializationService();

          nodeEngine
              .getExecutionService()
              .getExecutor(ExecutionService.ASYNC_EXECUTOR)
              .execute(
                  new Runnable() {
                    public void run() {
                      final BufferObjectDataOutput out =
                          serializationService.createObjectDataOutput(1024 * 32);
                      try {
                        out.writeInt(tasks.size());
                        for (Operation task : tasks) {
                          serializationService.writeObject(out, task);
                        }
                        final byte[] data;
                        boolean compress =
                            nodeEngine
                                .getGroupProperties()
                                .PARTITION_MIGRATION_ZIP_ENABLED
                                .getBoolean();
                        if (compress) {
                          data = IOUtil.compress(out.toByteArray());
                        } else {
                          data = out.toByteArray();
                        }
                        final MigrationOperation migrationOperation =
                            new MigrationOperation(
                                migrationInfo, replicaVersions, data, tasks.size(), compress);
                        Invocation inv =
                            nodeEngine
                                .getOperationService()
                                .createInvocationBuilder(
                                    PartitionServiceImpl.SERVICE_NAME,
                                    migrationOperation,
                                    destination)
                                .setTryPauseMillis(1000)
                                .setReplicaIndex(getReplicaIndex())
                                .build();
                        Future future = inv.invoke();
                        Boolean result =
                            (Boolean) nodeEngine.toObject(future.get(timeout, TimeUnit.SECONDS));
                        responseHandler.sendResponse(result);
                      } catch (Throwable e) {
                        responseHandler.sendResponse(Boolean.FALSE);
                        if (e instanceof ExecutionException) {
                          e = e.getCause() != null ? e.getCause() : e;
                        }
                        Level level =
                            (e instanceof MemberLeftException || e instanceof InterruptedException)
                                    || !getNodeEngine().isActive()
                                ? Level.INFO
                                : Level.WARNING;
                        getLogger().log(level, e.getMessage(), e);
                      } finally {
                        IOUtil.closeResource(out);
                      }
                    }
                  });
        } else {
          success = true;
        }
      } catch (Throwable e) {
        getLogger().warning(e);
        success = false;
      } finally {
        migrationInfo.doneProcessing();
      }
    } else {
      getLogger().warning("Migration is cancelled -> " + migrationInfo);
      success = false;
    }
  }
Exemple #7
0
  public LocalMapStatsImpl createLocalMapStats(String mapName) {
    MapContainer mapContainer = getMapContainer(mapName);
    LocalMapStatsImpl localMapStats = getLocalMapStatsImpl(mapName);
    if (!mapContainer.getMapConfig().isStatisticsEnabled()) {
      return localMapStats;
    }

    long ownedEntryCount = 0;
    long backupEntryCount = 0;
    long dirtyCount = 0;
    long ownedEntryMemoryCost = 0;
    long backupEntryMemoryCost = 0;
    long hits = 0;
    long lockedEntryCount = 0;
    long heapCost = 0;

    int backupCount = mapContainer.getTotalBackupCount();
    ClusterService clusterService = nodeEngine.getClusterService();
    final InternalPartitionService partitionService = nodeEngine.getPartitionService();

    Address thisAddress = clusterService.getThisAddress();
    for (int partitionId = 0; partitionId < partitionService.getPartitionCount(); partitionId++) {
      InternalPartition partition = partitionService.getPartition(partitionId);
      Address owner = partition.getOwner();
      if (owner == null) {
        // no-op because no owner is set yet. Therefor we don't know anything about the map
        continue;
      }
      if (owner.equals(thisAddress)) {
        PartitionContainer partitionContainer = getPartitionContainer(partitionId);
        RecordStore recordStore = partitionContainer.getExistingRecordStore(mapName);

        // we don't want to force loading the record store because we are loading statistics. So
        // that is why
        // we ask for 'getExistingRecordStore' instead of 'getRecordStore' which does the load.
        if (recordStore != null) {
          heapCost += recordStore.getHeapCost();
          Map<Data, Record> records = recordStore.getReadonlyRecordMap();
          for (Record record : records.values()) {
            RecordStatistics stats = record.getStatistics();
            // there is map store and the record is dirty (waits to be stored)
            ownedEntryCount++;
            ownedEntryMemoryCost += record.getCost();
            localMapStats.setLastAccessTime(stats.getLastAccessTime());
            localMapStats.setLastUpdateTime(stats.getLastUpdateTime());
            hits += stats.getHits();
            if (recordStore.isLocked(record.getKey())) {
              lockedEntryCount++;
            }
          }
        }
      } else {
        for (int replica = 1; replica <= backupCount; replica++) {
          Address replicaAddress = partition.getReplicaAddress(replica);
          int tryCount = 30;
          // wait if the partition table is not updated yet
          while (replicaAddress == null
              && clusterService.getSize() > backupCount
              && tryCount-- > 0) {
            try {
              Thread.sleep(100);
            } catch (InterruptedException e) {
              throw ExceptionUtil.rethrow(e);
            }
            replicaAddress = partition.getReplicaAddress(replica);
          }

          if (replicaAddress != null && replicaAddress.equals(thisAddress)) {
            PartitionContainer partitionContainer = getPartitionContainer(partitionId);
            RecordStore recordStore = partitionContainer.getRecordStore(mapName);
            heapCost += recordStore.getHeapCost();

            Map<Data, Record> records = recordStore.getReadonlyRecordMap();
            for (Record record : records.values()) {
              backupEntryCount++;
              backupEntryMemoryCost += record.getCost();
            }
          } else if (replicaAddress == null && clusterService.getSize() > backupCount) {
            logger.warning("Partition: " + partition + ", replica: " + replica + " has no owner!");
          }
        }
      }
    }

    if (mapContainer.getMapStoreScheduler() != null) {
      dirtyCount = mapContainer.getMapStoreScheduler().size();
    }
    localMapStats.setBackupCount(backupCount);
    localMapStats.setDirtyEntryCount(zeroOrPositive(dirtyCount));
    localMapStats.setLockedEntryCount(zeroOrPositive(lockedEntryCount));
    localMapStats.setHits(zeroOrPositive(hits));
    localMapStats.setOwnedEntryCount(zeroOrPositive(ownedEntryCount));
    localMapStats.setBackupEntryCount(zeroOrPositive(backupEntryCount));
    localMapStats.setOwnedEntryMemoryCost(zeroOrPositive(ownedEntryMemoryCost));
    localMapStats.setBackupEntryMemoryCost(zeroOrPositive(backupEntryMemoryCost));
    // add near cache heap cost.
    heapCost += mapContainer.getNearCacheSizeEstimator().getSize();
    localMapStats.setHeapCost(heapCost);
    if (mapContainer.getMapConfig().isNearCacheEnabled()) {
      NearCacheStatsImpl nearCacheStats = getNearCache(mapName).getNearCacheStats();
      localMapStats.setNearCacheStats(nearCacheStats);
    }

    return localMapStats;
  }