PrefetchInterceptor wraps the cache publishers/streams/iterators to block emitting a key from a segment that is in the BLOCKED/KEY_TRANSFER/VALUE_TRANSFER state, until the values are received and the segment goes into the OWNED stage. The subscription happens on non-blocking threads, so they should be wrapped in blockingManager.blockingPublisher() to move the subscription to a blocking thread.
In the worst case, StateConsumerImpl completes StateTransferLock.topologyFuture() in the middle topology update and triggers the retry of a publisher for the segments of a suspected node. If the segments are now local, they are in the BLOCKED state, so the publisher blocks. But the very fact that the publisher blocks on the topology update thread is preventing the topology update to continue and to request the keys, keeping the segments in the BLOCKED state. This is what's causing the random failures in ScatteredStreamIteratorTest.verifyNodeLeavesAfterSendingBackSomeData (