com.hazelcast.internal.nearcache.impl.invalidation.MetaDataFetcher Maven / Gradle / Ivy
/*
* 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.internal.nearcache.impl.invalidation;
import com.hazelcast.logging.ILogger;
import com.hazelcast.spi.InternalCompletableFuture;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
/**
* Runs on Near Cache side, an instance of this task is responsible for fetching of all Near Caches' remote metadata like last
* sequence numbers and partition UUIDs. To see usage of this metadata visit: {@link MetaDataGenerator}.
*
* This class is abstract to provide different implementations on client and member sides.
*/
public abstract class MetaDataFetcher {
protected static final int ASYNC_RESULT_WAIT_TIMEOUT_MINUTES = 1;
protected final ILogger logger;
public MetaDataFetcher(ILogger logger) {
this.logger = logger;
}
protected abstract void extractAndPopulateResult(InternalCompletableFuture future, ResultHolder resultHolder)
throws Exception;
protected abstract List scanMembers(List names);
public final void init(RepairingHandler handler) throws Exception {
ResultHolder resultHolder = new ResultHolder();
List futures = scanMembers(Collections.singletonList(handler.getName()));
for (InternalCompletableFuture future : futures) {
extractAndPopulateResult(future, resultHolder);
initUuid(resultHolder.partitionUuidList, handler);
initSequence(resultHolder.namePartitionSequenceList, handler);
}
}
public final void process(InternalCompletableFuture future, ConcurrentMap handlers) {
try {
ResultHolder resultHolder = new ResultHolder();
extractAndPopulateResult(future, resultHolder);
repairUuids(resultHolder.partitionUuidList, handlers);
repairSequences(resultHolder.namePartitionSequenceList, handlers);
} catch (Exception e) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Can't fetch invalidation meta-data [" + e.getClass().getSimpleName() + "] " + e.getMessage());
}
}
}
public final void fetchMetadata(ConcurrentMap handlers) {
if (handlers.isEmpty()) {
return;
}
List mapNames = getNames(handlers);
List futures = scanMembers(mapNames);
for (InternalCompletableFuture future : futures) {
process(future, handlers);
}
}
private List getNames(ConcurrentMap handlers) {
List names = new ArrayList(handlers.size());
for (RepairingHandler handler : handlers.values()) {
names.add(handler.getName());
}
return names;
}
protected void repairUuids(Collection> uuids, ConcurrentMap handlers) {
for (Map.Entry entry : uuids) {
for (RepairingHandler handler : handlers.values()) {
handler.checkOrRepairUuid(entry.getKey(), entry.getValue());
}
}
}
protected void initUuid(Collection> uuids, RepairingHandler handler) {
for (Map.Entry entry : uuids) {
int partitionID = entry.getKey();
UUID partitionUuid = entry.getValue();
handler.initUuid(partitionID, partitionUuid);
}
}
protected void repairSequences(Collection>>> namePartitionSequenceList,
ConcurrentMap handlers) {
for (Map.Entry>> entry : namePartitionSequenceList) {
for (Map.Entry subEntry : entry.getValue()) {
RepairingHandler repairingHandler = handlers.get(entry.getKey());
repairingHandler.checkOrRepairSequence(subEntry.getKey(), subEntry.getValue(), true);
}
}
}
protected void initSequence(Collection>>> namePartitionSequenceList,
RepairingHandler handler) {
for (Map.Entry>> entry : namePartitionSequenceList) {
for (Map.Entry subEntry : entry.getValue()) {
int partitionID = subEntry.getKey();
long partitionSequence = subEntry.getValue();
handler.initSequence(partitionID, partitionSequence);
}
}
}
protected static class ResultHolder {
private Collection>>> namePartitionSequenceList;
private Collection> partitionUuidList;
public void populate(Collection> partitionUuidList,
Collection>>> namePartitionSequenceList) {
this.namePartitionSequenceList = namePartitionSequenceList;
this.partitionUuidList = partitionUuidList;
}
}
}