/** * Copyright 2016 LinkedIn Corp. 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. */ package com.github.ambry.router; import com.github.ambry.clustermap.ReplicaId; import java.util.Iterator; /** * An operation is an action that a router takes to handle a request it receives. An operation * will then send requests to multiple replicas. An operation succeeds if a pre-set number of * successful responses are received from the replicas, or fails if this number cannot be met. * * An {@code OperationTracker} tracks and determines the status of an operation, and decides the * next replica to send a request. * * When an operation is progressing by receiving responses from replicas, its {@code OperationTracker} * needs to be informed by calling {@link #onResponse(ReplicaId, boolean)}. * * Typical usage of an {@code OperationTracker} would be: * <pre> *{@code * * Operation operationTracker = new OperationTrackerImpl(..); * //... * Iterator<ReplicaId> itr = operationTracker.getReplicaIterator(); * while (itr.hasNext()) { * ReplicaId nextReplica = itr.next(); * //determine request can be sent to the replica, i.e., connection available. * if(true) { * itr.remove(); * } * } *} * </pre> */ interface OperationTracker { /** * Determines if an operation has succeeded. * * @return {@code true} if the operation has successfully completed. */ boolean hasSucceeded(); /** * Determines if an operation has completed (either succeeded or failed). * * @return {@code true} if the operation has completed. */ boolean isDone(); /** * Accounts for successful or failed response from a replica. Must invoke this method * if a successful or failed response is received for a replica. * * @param replicaId ReplicaId associated with this response. * @param isSuccessful Whether the request to the replicaId is successful or not. */ void onResponse(ReplicaId replicaId, boolean isSuccessful); /** * Provide an iterator to the replicas to which requests may be sent. Each time when start to iterate * the replicas of an {@code OperationTracker}, an iterator needs to be obtained by calling this * method. If a request is sent to a {@link ReplicaId} obtained from the returned iterator, the {@link ReplicaId} * has to be removed from the iterator in order for it to be tracked. * * @return An iterator that iterates all possible and valid replicas. */ Iterator<ReplicaId> getReplicaIterator(); }