/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hazelcast.spi; /** * An interface that can be implemented by SPI services to get notified of partition changes; for example, if a * {@link com.hazelcast.map.impl.MapService} starts moving its data around because partitions are moving * to a different machine. * <p> * Service itself must decide to keep or remove its data for specific partition according to number of backups * it's willing to keep and {@code PartitionMigrationEvent} parameters; partitionId, migration-endpoint, * current replica index and new replica index. * <ul> * <li>Migration endpoint shows which endpoint this member is; either {@code SOURCE} or {@code DESTINATION} </li> * <li>Current replica index denotes the replica index which is currently owned by this member before migration.</li> * <li>New replica index denotes the replica index which will be owned by this member after migration.</li> * </ul> * <p> * On migration source, partition replica will be either removed completely or shifted down to a higher indexed replica. * During commit, service should remove either all or some part of its data in this partition * and run any other action needed. A sample commit on source will look like; * <pre> * <code> * public void commitMigration(PartitionMigrationEvent event) { * if (event.getMigrationEndpoint() == MigrationEndpoint.SOURCE) { * if (event.getNewReplicaIndex() == -1 || event.getNewReplicaIndex() > configuredBackupCount) { * // remove data... * } * } * // run any other task needed * } * </code> * </pre> * During rollback, source usually doesn't expected to perform any task. But service implementation may need * to execute custom tasks. * <p> * On migration destination, either a fresh partition replica will be received or current replica will be * shifted up to a lower indexed replica. * During rollback, service should remove either all or some part of its data in this partition * and run any other action needed. A sample rollback on destination will look like; * <pre> * <code> * public void rollbackMigration(PartitionMigrationEvent event) { * if (event.getMigrationEndpoint() == MigrationEndpoint.DESTINATION) { * if (event.getCurrentReplicaIndex() == -1 || event.getCurrentReplicaIndex() > configuredBackupCount) { * // remove data... * } * } * // run any other task needed * } * </code> * </pre> * <p> * During commit, destination usually doesn't expected to perform any task. But service implementation may need * to execute custom tasks. */ public interface MigrationAwareService { /** * Returns an operation to replicate service data and/or state for a specific partition replica * on another cluster member. * <p> * This method will be called on source member whenever partitioning system requires * to copy/replicate a partition replica. Returned operation will be executed on destination member. * If operation fails by throwing exception, migration process will fail and will be rolled back. * <p> * Returning null is allowed and means service does not have anything to replicate. * * @param event replication * @return replication operation or null if nothing will be replicated */ Operation prepareReplicationOperation(PartitionReplicationEvent event); /** * Called before migration process starts, on both source and destination members. * <p> * Service can take actions required before migration. Migration process will block until this method returns. * If this method fails by throwing an exception, migration process for specific partition will fail * and will be rolled back. * * @param event migration event */ void beforeMigration(PartitionMigrationEvent event); /** * Commits the migration process for this service, on both source and destination members. * This method will be called after all replication operations are executed successfully on destination * and master member receives success response from all participants. * <p> * Commit is not expected to fail at this point, all exceptions will be suppressed and logged. * * @param event migration event */ void commitMigration(PartitionMigrationEvent event); /** * Rollback the migration process for this service, on both source and destination members. * This method will be called when migration process fails at any moment. * Reasons for failure may be an exception thrown on any migration step * or failure(s) of any of the migration participants; either master or source or destination. * <p> * Rollback is not expected to fail at this point, all exceptions will be suppressed and logged. * * @param event migration event */ void rollbackMigration(PartitionMigrationEvent event); }