I have created a Many
sink into which I produce items from multiple threads:
Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();
// below just dummy code to simulate parallel producer
Flux.range(1, 1000)
.parallel()
.runOn(Schedulers.parallel())
.map(String::valueOf)
.doOnNext(t -> {
sink.emitNext(t, (signal, failure) -> {
System.out.println(failure);
return failure == Sinks.EmitResult.FAIL_NON_SERIALIZED;
});
})
.sequential()
.count()
.doOnNext(System.out::println)
.block();
By default the sink does not allow emitting items to it parallelly from many threads and throws a Sinks$EmissionException
and states that Spec. Rule 1.3 - onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially.
. Fortunately, the Reactor library offers a way to handle this so I can pass an EmitFailureHandler
to the emitNext
method which is basically a BiPredicate
in which I can define whether I would like Reactor to retry emission. In the above example the code retries emission every time it encounters this failure.
Is this correct way of handling this error? Is there any drawback like retries exhausting CPU or potential deadlock? Is there a more efficient way to implement this?