Search in sources :

Example 1 with PublisherResponse

use of org.infinispan.reactive.publisher.impl.commands.batch.PublisherResponse in project infinispan by infinispan.

the class InnerPublisherSubscription method accept.

/**
 * This method is invoked every time a new request is sent to the underlying publisher. We need to submit a request
 * if there is not a pending one. Whenever requestedAmount is a number greater than 0, that means we must submit or
 * there is a pending one.
 * @param count request count
 */
@Override
public void accept(long count) {
    if (shouldSubmit(count)) {
        if (checkCancelled()) {
            return;
        }
        // Find which address and segments we still need to retrieve - when the supplier returns null that means
        // we don't need to do anything else (normal termination state)
        Map.Entry<Address, IntSet> target = currentTarget;
        if (target == null) {
            alreadyCreated = false;
            target = builder.supplier.get();
            if (target == null) {
                if (log.isTraceEnabled()) {
                    log.tracef("Completing processor %s", flowableProcessor);
                }
                flowableProcessor.onComplete();
                return;
            } else {
                currentTarget = target;
            }
        }
        ClusterPublisherManagerImpl<K, ?>.SubscriberHandler<I, R> parent = builder.parent;
        CompletionStage<PublisherResponse> stage;
        Address address = target.getKey();
        IntSet segments = target.getValue();
        try {
            if (alreadyCreated) {
                stage = parent.sendNextCommand(address, builder.topologyId);
            } else {
                alreadyCreated = true;
                stage = parent.sendInitialCommand(address, segments, builder.batchSize, builder.excludedKeys.remove(address), builder.topologyId);
            }
        } catch (Throwable t) {
            handleThrowableInResponse(t, address, segments);
            return;
        }
        stage.whenComplete((values, t) -> {
            if (t != null) {
                handleThrowableInResponse(CompletableFutures.extractException(t), address, segments);
                return;
            }
            try {
                if (log.isTraceEnabled()) {
                    // Note the size of the array may not be the amount of entries as it isn't resized (can contain nulls)
                    log.tracef("Received %s for id %s from %s", values, parent.requestId, address);
                }
                IntSet completedSegments = values.getCompletedSegments();
                if (completedSegments != null) {
                    if (log.isTraceEnabled()) {
                        log.tracef("Completed segments %s for id %s from %s", completedSegments, parent.requestId, address);
                    }
                    completedSegments.forEach((IntConsumer) parent::completeSegment);
                    completedSegments.forEach((IntConsumer) segments::remove);
                }
                IntSet lostSegments = values.getLostSegments();
                if (lostSegments != null) {
                    if (log.isTraceEnabled()) {
                        log.tracef("Lost segments %s for id %s from %s", completedSegments, parent.requestId, address);
                    }
                    lostSegments.forEach((IntConsumer) segments::remove);
                }
                boolean complete = values.isComplete();
                if (complete) {
                    // Current address has returned all values it can - setting to null will force the next invocation
                    // of this method try the next target if available
                    currentTarget = null;
                } else {
                    values.keysForNonCompletedSegments(parent);
                }
                R[] valueArray = (R[]) values.getResults();
                if (values instanceof KeyPublisherResponse) {
                    KeyPublisherResponse kpr = (KeyPublisherResponse) values;
                    int extraSize = kpr.getExtraSize();
                    if (extraSize > 0) {
                        int arrayLength = valueArray.length;
                        Object[] newArray = new Object[arrayLength + extraSize];
                        System.arraycopy(valueArray, 0, newArray, 0, arrayLength);
                        System.arraycopy(kpr.getExtraObjects(), 0, newArray, arrayLength, extraSize);
                        valueArray = (R[]) newArray;
                    }
                }
                int pos = 0;
                for (PublisherHandler.SegmentResult segmentResult : values.getSegmentResults()) {
                    if (checkCancelled()) {
                        return;
                    }
                    int segment = segmentResult.getSegment();
                    for (int i = 0; i < segmentResult.getEntryCount(); ++i) {
                        R value = valueArray[pos++];
                        doOnValue(value, segment);
                    }
                    if (completedSegments != null && completedSegments.remove(segment)) {
                        doOnSegmentComplete(segment);
                    }
                }
                // Any completed segments left were empty, just complete them together
                if (completedSegments != null) {
                    completedSegments.forEach((IntConsumer) this::doOnSegmentComplete);
                }
                accept(-pos);
            } catch (Throwable innerT) {
                handleThrowableInResponse(innerT, address, segments);
            }
        });
    }
}
Also used : KeyPublisherResponse(org.infinispan.reactive.publisher.impl.commands.batch.KeyPublisherResponse) Address(org.infinispan.remoting.transport.Address) IntSet(org.infinispan.commons.util.IntSet) IntConsumer(java.util.function.IntConsumer) KeyPublisherResponse(org.infinispan.reactive.publisher.impl.commands.batch.KeyPublisherResponse) PublisherResponse(org.infinispan.reactive.publisher.impl.commands.batch.PublisherResponse) Map(java.util.Map)

Aggregations

Map (java.util.Map)1 IntConsumer (java.util.function.IntConsumer)1 IntSet (org.infinispan.commons.util.IntSet)1 KeyPublisherResponse (org.infinispan.reactive.publisher.impl.commands.batch.KeyPublisherResponse)1 PublisherResponse (org.infinispan.reactive.publisher.impl.commands.batch.PublisherResponse)1 Address (org.infinispan.remoting.transport.Address)1