Class BaseProcessor<T,​U>

  • Type Parameters:
    T - subscribed type (input)
    U - published type (output)
    All Implemented Interfaces:
    Flow.Processor<T,​U>, Flow.Publisher<U>, Flow.Subscriber<T>, Flow.Subscription
    Direct Known Subclasses:
    MultiFilterProcessor, MultiFlatMapProcessor, MultiMapProcessor, MultiPeekProcessor, MultiTappedProcessor

    public abstract class BaseProcessor<T,​U>
    extends Object
    implements Flow.Processor<T,​U>, Flow.Subscription
    A generic processor used for the implementation of Multi and Single.

    Implementing Processor interface, delegating invocations to downstreamSubscribe, next and complete at the right times

    Such right times are:

    • 1. downstream onSubscription - only after both downstream called subscribe and upstream called onSubscription
    • 2. downstream onNext - will not happen before request(...)
    • 3. upstream request / cancel - will not happen before request(...) / cancel()
    • 4. request(...) / cancel() - will not happend before downstream onSubscription
    • 5. downstream onError / onComplete - will not happen before downstream onSubcription
    • 6. upstream onError / onComplete - may happen any time after upstream onSubscription, so keep track of upstream completion
    • 7. upstream onNext - will not happen before request(...)

    The order in which subscribe and onSubscription get called is not defined, so if you want to interact with upstream before downstreamSubscribe is called, you need to take care of the possibility that the downstream may have not called subscribe() yet (ie is not set up). In that case you may be better off implementing Processor yourself, not subclassing from BaseProcessor.

    downstreamSubscribe needs to be called once and only once, whereas subscribe and onSubscription may be called by different threads - so ensuring atomicity of Subscriber's state transition. These methods are meant to be called only once, and by no more than one thread each, no need to do anything more complicated than synchronized.

    • Constructor Detail

      • BaseProcessor

        public BaseProcessor()
    • Method Detail

      • downstreamSubscribe

        protected void downstreamSubscribe()
        This is invoked when this processor is in a state when both upstream and downstream subscriptions have been set up.
      • complete

        protected void complete​(Throwable ex)
        This is invoked when this processor needs to signal onError or onComplete to downstream, and the downstream Subscriber is in a state that is allowed to receive onError / onComplete. It calls cancel(), too, although cancellation is not required, but we can do that as best effort CPU-saving
        Parameters:
        ex - Exception to complete exceptionally with
      • complete

        protected void complete()
        Complete by sending onComplete signal to down stream.
      • next

        protected void next​(T item)
        This is invoked when this processor receives onNext, and downstream Subscriber is in a state that is allowed to receive onNext.
        Parameters:
        item - to be sent to down stream
      • submit

        protected abstract void submit​(T item)
        Invoke actual onNext signal to down stream.
        Parameters:
        item - to be sent down stream
      • onSubscribe

        public void onSubscribe​(Flow.Subscription sub)
        All Subscriber method invocations are guaranteed to be in total order by Publisher specification, so no need to do anything special.
        Specified by:
        onSubscribe in interface Flow.Subscriber<T>
      • request

        public void request​(long n)
        request and cancel are not guaranteed to be thread-safe by the Publisher but this is not interacting with any state of this Processor - thread-safety is sub's concern - eventually the problem of the Publisher that provides the highest level Subscription.
        Specified by:
        request in interface Flow.Subscription
      • setError

        protected void setError​(Throwable error)