use of org.infinispan.configuration.cache.Configurations in project infinispan by infinispan.
the class ScatteredStateConsumerImpl method onTaskCompletion.
@Override
protected void onTaskCompletion(InboundTransferTask inboundTransfer) {
// a bit of overkill since we start these tasks for single segment
IntSet completedSegments = IntSets.immutableEmptySet();
if (log.isTraceEnabled())
log.tracef("Inbound transfer finished %s: %s", inboundTransfer, inboundTransfer.isCompletedSuccessfully() ? "successfully" : "unsuccessfuly");
synchronized (transferMapsLock) {
// transferMapsLock is held when all the tasks are added so we see that all of them are done
for (PrimitiveIterator.OfInt iter = inboundTransfer.getSegments().iterator(); iter.hasNext(); ) {
int segment = iter.nextInt();
List<InboundTransferTask> transfers = transfersBySegment.get(segment);
if (transfers == null) {
// It is possible that two task complete concurrently, one of them checks is all tasks
// for given segments have been completed successfully and (finding out that it's true)
// removes the transfer for given segment. The second task arrives and finds out that
// its record int transfersBySegment is gone, but that's OK, as the segment has been handled.
log.tracef("Transfers for segment %d have not been found.", segment);
} else {
// We are removing here rather than in removeTransfer, because we need to know if we're the last
// finishing task.
transfers.remove(inboundTransfer);
if (transfers.isEmpty()) {
transfersBySegment.remove(segment);
if (log.isTraceEnabled()) {
log.tracef("All transfer tasks for segment %d have completed.", segment);
}
svm.notifyKeyTransferFinished(segment, inboundTransfer.isCompletedSuccessfully(), inboundTransfer.isCancelled());
switch(completedSegments.size()) {
case 0:
completedSegments = IntSets.immutableSet(segment);
break;
case 1:
completedSegments = IntSets.mutableCopyFrom(completedSegments);
// Intentional falls through
default:
completedSegments.set(segment);
}
}
}
}
}
if (completedSegments.isEmpty()) {
log.tracef("Not requesting any values yet because no segments have been completed.");
} else if (inboundTransfer.isCompletedSuccessfully()) {
log.tracef("Requesting values from segments %s, for in-memory keys", completedSegments);
dataContainer.forEach(completedSegments, ice -> {
// TODO: could the version be null in here?
if (ice.getMetadata() instanceof RemoteMetadata) {
Address backup = ((RemoteMetadata) ice.getMetadata()).getAddress();
retrieveEntry(ice.getKey(), backup);
for (Address member : cacheTopology.getActualMembers()) {
if (!member.equals(backup)) {
invalidate(ice.getKey(), ice.getMetadata().version(), member);
}
}
} else {
backupEntry(ice);
for (Address member : nonBackupAddresses) {
invalidate(ice.getKey(), ice.getMetadata().version(), member);
}
}
});
// With passivation, some key could be activated here and we could miss it,
// but then it should be broadcast-loaded in PrefetchInvalidationInterceptor
Publisher<MarshallableEntry<Object, Object>> persistencePublisher = persistenceManager.publishEntries(completedSegments, k -> dataContainer.peek(k) == null, true, true, Configurations::isStateTransferStore);
try {
blockingSubscribe(Flowable.fromPublisher(persistencePublisher).doOnNext(me -> {
try {
Metadata metadata = me.getMetadata();
if (metadata instanceof RemoteMetadata) {
Address backup = ((RemoteMetadata) metadata).getAddress();
retrieveEntry(me.getKey(), backup);
for (Address member : cacheTopology.getActualMembers()) {
if (!member.equals(backup)) {
invalidate(me.getKey(), metadata.version(), member);
}
}
} else {
backupEntry(entryFactory.create(me.getKey(), me.getValue(), me.getMetadata()));
for (Address member : nonBackupAddresses) {
invalidate(me.getKey(), metadata.version(), member);
}
}
} catch (CacheException e) {
log.failedLoadingValueFromCacheStore(me.getKey(), e);
}
}));
} catch (CacheException e) {
PERSISTENCE.failedLoadingKeysFromCacheStore(e);
}
}
boolean lastTransfer = false;
synchronized (transferMapsLock) {
inboundSegments.removeAll(completedSegments);
log.tracef("Unfinished inbound segments: " + inboundSegments);
if (inboundSegments.isEmpty()) {
lastTransfer = true;
}
}
if (lastTransfer) {
for (Map.Entry<Address, BlockingQueue<Object>> pair : retrievedEntries.entrySet()) {
BlockingQueue<Object> queue = pair.getValue();
List<Object> keys = new ArrayList<>(queue.size());
queue.drainTo(keys);
if (!keys.isEmpty()) {
getValuesAndApply(pair.getKey(), keys);
}
}
List<InternalCacheEntry<?, ?>> entries = new ArrayList<>(backupQueue.size());
backupQueue.drainTo(entries);
if (!entries.isEmpty()) {
backupEntries(entries);
}
for (Map.Entry<Address, BlockingQueue<KeyAndVersion>> pair : invalidations.entrySet()) {
BlockingQueue<KeyAndVersion> queue = pair.getValue();
List<KeyAndVersion> list = new ArrayList<>(queue.size());
queue.drainTo(list);
if (!list.isEmpty()) {
invalidate(list, pair.getKey());
}
}
}
// we must not remove the transfer before the requests for values are sent
// as we could notify the end of rebalance too soon
removeTransfer(inboundTransfer);
if (lastTransfer) {
if (log.isTraceEnabled())
log.tracef("Inbound transfer removed, chunk counter is %s", chunkCounter.get());
if (chunkCounter.get() == 0) {
// No values to transfer after all the keys were received, we can end state transfer immediately
notifyEndOfStateTransferIfNeeded();
}
}
}
use of org.infinispan.configuration.cache.Configurations in project infinispan by infinispan.
the class ScatteredStateProviderImpl method publishStoreKeys.
private Flowable<InternalCacheEntry<Object, Object>> publishStoreKeys(IntSet segments) {
Address localAddress = rpcManager.getAddress();
Publisher<MarshallableEntry<Object, Object>> loaderPublisher = persistenceManager.publishEntries(segments, k -> dataContainer.peek(k) == null, true, true, Configurations::isStateTransferStore);
return Flowable.fromPublisher(loaderPublisher).filter(me -> me.getMetadata() != null && me.getMetadata().version() != null).map(me -> entryFactory.create(me.getKey(), null, new RemoteMetadata(localAddress, me.getMetadata().version())));
}
Aggregations