use of com.hazelcast.internal.partition.impl.MigrationStats in project hazelcast by hazelcast.
the class PartitionMigrationListenerTest method testMigrationStats_whenMigrationProcessRestarts.
@Test
public void testMigrationStats_whenMigrationProcessRestarts() {
TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory();
Config config = new Config();
int partitionCount = 100;
config.setProperty(ClusterProperty.PARTITION_COUNT.getName(), String.valueOf(partitionCount));
config.setProperty(ClusterProperty.PARTITION_MAX_PARALLEL_MIGRATIONS.getName(), String.valueOf(1));
HazelcastInstance hz1 = factory.newHazelcastInstance(config);
warmUpPartitions(hz1);
InternalPartitionServiceImpl partitionService = (InternalPartitionServiceImpl) getPartitionService(hz1);
AtomicReference<HazelcastInstance> newInstanceRef = new AtomicReference<>();
partitionService.setMigrationInterceptor(new MigrationInterceptor() {
@Override
public void onMigrationComplete(MigrationParticipant participant, MigrationInfo migration, boolean success) {
MigrationStats stats = partitionService.getMigrationManager().getStats();
if (stats.getRemainingMigrations() < 50) {
// start a new member to restart migrations
partitionService.resetMigrationInterceptor();
HazelcastInstance hz = factory.newHazelcastInstance(config);
assertClusterSize(3, hz);
newInstanceRef.set(hz);
}
}
});
EventCollectingMigrationListener listener = new EventCollectingMigrationListener();
hz1.getPartitionService().addMigrationListener(listener);
// Change to NO_MIGRATION to prevent repartitioning
// before 2nd member started and ready.
hz1.getCluster().changeClusterState(ClusterState.NO_MIGRATION);
// trigger migrations
HazelcastInstance hz2 = factory.newHazelcastInstance(config);
// Back to ACTIVE
changeClusterStateEventually(hz2, ClusterState.ACTIVE);
// await until 3rd member joins
assertClusterSizeEventually(3, hz1);
assertTrueEventually(() -> assertNotNull(newInstanceRef.get()));
List<MigrationEventsPack> eventsPackList = listener.ensureAndGetEventPacks(2);
// 1st migration process, which finishes without completing all migration tasks
MigrationEventsPack firstEventsPack = eventsPackList.get(0);
assertMigrationProcessCompleted(firstEventsPack);
MigrationState migrationResult = firstEventsPack.migrationProcessCompleted;
assertThat(migrationResult.getCompletedMigrations(), lessThan(migrationResult.getPlannedMigrations()));
assertThat(migrationResult.getRemainingMigrations(), greaterThan(0));
assertMigrationEventsConsistentWithResult(firstEventsPack);
// 2nd migration process finishes by consuming all migration tasks
MigrationEventsPack secondEventsPack = eventsPackList.get(1);
if (secondEventsPack.migrationProcessCompleted.getCompletedMigrations() == 1 && !secondEventsPack.migrationsCompleted.get(0).isSuccess()) {
// There is a failed migration process
// because migrations restarted before 3rd member is ready.
// This migration process is failed immediately
// and we expect a third migration process.
secondEventsPack = listener.ensureAndGetEventPacks(3).get(2);
}
assertMigrationProcessCompleted(secondEventsPack);
assertMigrationProcessEventsConsistent(secondEventsPack);
assertMigrationEventsConsistentWithResult(secondEventsPack);
}
Aggregations