com.hazelcast.scheduledexecutor.impl.InvokeOnMembers Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2023, 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.scheduledexecutor.impl;
import com.hazelcast.cluster.Member;
import com.hazelcast.logging.ILogger;
import com.hazelcast.spi.impl.NodeEngine;
import com.hazelcast.spi.impl.operationservice.Operation;
import com.hazelcast.spi.impl.operationservice.OperationService;
import com.hazelcast.spi.annotation.PrivateApi;
import com.hazelcast.internal.serialization.SerializationService;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.function.Supplier;
/**
* Executes an operation on a set of targets. Similar to {@link com.hazelcast.spi.impl.operationservice.impl.InvokeOnPartitions}
* but for members.
*/
@PrivateApi
public final class InvokeOnMembers {
private static final int TRY_COUNT = 10;
private static final int TRY_PAUSE_MILLIS = 300;
private final ILogger logger;
private final OperationService operationService;
private final SerializationService serializationService;
private final String serviceName;
private final Supplier operationFactory;
private final Collection targets;
private final Map futures;
private final Map results;
public InvokeOnMembers(NodeEngine nodeEngine, String serviceName, Supplier operationFactory,
Collection targets) {
this.logger = nodeEngine.getLogger(getClass());
this.operationService = nodeEngine.getOperationService();
this.serializationService = nodeEngine.getSerializationService();
this.serviceName = serviceName;
this.operationFactory = operationFactory;
this.targets = targets;
this.futures = new HashMap(targets.size());
this.results = new HashMap(targets.size());
}
/**
* Executes the operation on all targets.
*/
public Map invoke()
throws Exception {
invokeOnAllTargets();
awaitCompletion();
retryFailedTargets();
return results;
}
private void invokeOnAllTargets() {
for (Member target : targets) {
Future future = operationService.createInvocationBuilder(serviceName, operationFactory.get(), target.getAddress())
.setTryCount(TRY_COUNT).setTryPauseMillis(TRY_PAUSE_MILLIS).invoke();
futures.put(target, future);
}
}
private void awaitCompletion() {
for (Map.Entry responseEntry : futures.entrySet()) {
try {
Future future = responseEntry.getValue();
results.put(responseEntry.getKey(), serializationService.toObject(future.get()));
} catch (Throwable t) {
if (logger.isFinestEnabled()) {
logger.finest(t);
} else {
logger.warning(t.getMessage());
}
results.put(responseEntry.getKey(), t);
}
}
}
private void retryFailedTargets()
throws InterruptedException, ExecutionException {
List failedMembers = new LinkedList();
for (Map.Entry memberResult : results.entrySet()) {
Member member = memberResult.getKey();
Object result = memberResult.getValue();
if (result instanceof Throwable) {
failedMembers.add(member);
}
}
for (Member failedMember : failedMembers) {
Operation operation = operationFactory.get();
Future future = operationService.createInvocationBuilder(serviceName, operation, failedMember.getAddress()).invoke();
results.put(failedMember, future);
}
for (Member failedMember : failedMembers) {
Future future = (Future) results.get(failedMember);
Object result = future.get();
results.put(failedMember, result);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy