SubmissionPublisher Class

Definition

A Flow.Publisher that asynchronously issues submitted (non-null) items to current subscribers until it is closed.

[Android.Runtime.Register("java/util/concurrent/SubmissionPublisher", ApiSince=33, DoNotGenerateAcw=true)]
[Java.Interop.JavaTypeParameters(new System.String[] { "T" })]
public class SubmissionPublisher : Java.Lang.Object, IDisposable, Java.Interop.IJavaPeerable, Java.Lang.IAutoCloseable, Java.Util.Concurrent.Flow.IPublisher
[<Android.Runtime.Register("java/util/concurrent/SubmissionPublisher", ApiSince=33, DoNotGenerateAcw=true)>]
[<Java.Interop.JavaTypeParameters(new System.String[] { "T" })>]
type SubmissionPublisher = class
    inherit Object
    interface IAutoCloseable
    interface IJavaObject
    interface IDisposable
    interface IJavaPeerable
    interface Flow.IPublisher
Inheritance
SubmissionPublisher
Attributes
Implements

Remarks

A Flow.Publisher that asynchronously issues submitted (non-null) items to current subscribers until it is closed. Each current subscriber receives newly submitted items in the same order unless drops or exceptions are encountered. Using a SubmissionPublisher allows item generators to act as compliant reactive-streams Publishers relying on drop handling and/or blocking for flow control.

A SubmissionPublisher uses the Executor supplied in its constructor for delivery to subscribers. The best choice of Executor depends on expected usage. If the generator(s) of submitted items run in separate threads, and the number of subscribers can be estimated, consider using a Executors#newFixedThreadPool. Otherwise consider using the default, normally the ForkJoinPool#commonPool.

Buffering allows producers and consumers to transiently operate at different rates. Each subscriber uses an independent buffer. Buffers are created upon first use and expanded as needed up to the given maximum. (The enforced capacity may be rounded up to the nearest power of two and/or bounded by the largest value supported by this implementation.) Invocations of Flow.Subscription#request(long) request do not directly result in buffer expansion, but risk saturation if unfilled requests exceed the maximum capacity. The default value of Flow#defaultBufferSize() may provide a useful starting point for choosing a capacity based on expected rates, resources, and usages.

A single SubmissionPublisher may be shared among multiple sources. Actions in a source thread prior to publishing an item or issuing a signal <i>happen-before</i> actions subsequent to the corresponding access by each subscriber. But reported estimates of lag and demand are designed for use in monitoring, not for synchronization control, and may reflect stale or inaccurate views of progress.

Publication methods support different policies about what to do when buffers are saturated. Method #submit(Object) submit blocks until resources are available. This is simplest, but least responsive. The offer methods may drop items (either immediately or with bounded timeout), but provide an opportunity to interpose a handler and then retry.

If any Subscriber method throws an exception, its subscription is cancelled. If a handler is supplied as a constructor argument, it is invoked before cancellation upon an exception in method Flow.Subscriber#onNext onNext, but exceptions in methods Flow.Subscriber#onSubscribe onSubscribe, Flow.Subscriber#onError(Throwable) onError and Flow.Subscriber#onComplete() onComplete are not recorded or handled before cancellation. If the supplied Executor throws RejectedExecutionException (or any other RuntimeException or Error) when attempting to execute a task, or a drop handler throws an exception when processing a dropped item, then the exception is rethrown. In these cases, not all subscribers will have been issued the published item. It is usually good practice to #closeExceptionally closeExceptionally in these cases.

Method #consume(Consumer) simplifies support for a common case in which the only action of a subscriber is to request and process all items using a supplied function.

This class may also serve as a convenient base for subclasses that generate items, and use the methods in this class to publish them. For example here is a class that periodically publishes the items generated from a supplier. (In practice you might add methods to independently start and stop generation, to share Executors among publishers, and so on, or use a SubmissionPublisher as a component rather than a superclass.)

{@code
            class PeriodicPublisher<T> extends SubmissionPublisher<T> {
              final ScheduledFuture<?> periodicTask;
              final ScheduledExecutorService scheduler;
              PeriodicPublisher(Executor executor, int maxBufferCapacity,
                                Supplier<? extends T> supplier,
                                long period, TimeUnit unit) {
                super(executor, maxBufferCapacity);
                scheduler = new ScheduledThreadPoolExecutor(1);
                periodicTask = scheduler.scheduleAtFixedRate(
                  () -> submit(supplier.get()), 0, period, unit);
              }
              public void close() {
                periodicTask.cancel(false);
                scheduler.shutdown();
                super.close();
              }
            }}

Here is an example of a Flow.Processor implementation. It uses single-step requests to its publisher for simplicity of illustration. A more adaptive version could monitor flow using the lag estimate returned from submit, along with other utility methods.

{@code
            class TransformProcessor<S,T> extends SubmissionPublisher<T>
              implements Flow.Processor<S,T> {
              final Function<? super S, ? extends T> function;
              Flow.Subscription subscription;
              TransformProcessor(Executor executor, int maxBufferCapacity,
                                 Function<? super S, ? extends T> function) {
                super(executor, maxBufferCapacity);
                this.function = function;
              }
              public void onSubscribe(Flow.Subscription subscription) {
                (this.subscription = subscription).request(1);
              }
              public void onNext(S item) {
                subscription.request(1);
                submit(function.apply(item));
              }
              public void onError(Throwable ex) { closeExceptionally(ex); }
              public void onComplete() { close(); }
            }}

Added in 9.

Java documentation for java.util.concurrent.SubmissionPublisher.

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

Constructors

SubmissionPublisher()

Creates a new SubmissionPublisher using the ForkJoinPool#commonPool() for async delivery to subscribers (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task), with maximum buffer capacity of Flow#defaultBufferSize, and no handler for Subscriber exceptions in method Flow.Subscriber#onNext(Object) onNext.

SubmissionPublisher(IExecutor, Int32, IBiConsumer)

Creates a new SubmissionPublisher using the given Executor for async delivery to subscribers, with the given maximum buffer size for each subscriber, and, if non-null, the given handler invoked when any Subscriber throws an exception in method Flow.Subscriber#onNext(Object) onNext.

SubmissionPublisher(IExecutor, Int32)

Creates a new SubmissionPublisher using the given Executor for async delivery to subscribers, with the given maximum buffer size for each subscriber, and no handler for Subscriber exceptions in method Flow.Subscriber#onNext(Object) onNext.

SubmissionPublisher(IntPtr, JniHandleOwnership)

Properties

Class

Returns the runtime class of this Object.

(Inherited from Object)
ClosedException

Returns the exception associated with #closeExceptionally(Throwable) closeExceptionally, or null if not closed or if closed normally.

Executor

Returns the Executor used for asynchronous delivery.

Handle

The handle to the underlying Android instance.

(Inherited from Object)
HasSubscribers

Returns true if this publisher has any subscribers.

IsClosed

Returns true if this publisher is not accepting submissions.

JniIdentityHashCode (Inherited from Object)
JniPeerMembers
MaxBufferCapacity

Returns the maximum per-subscriber buffer capacity.

NumberOfSubscribers

Returns the number of current subscribers.

PeerReference (Inherited from Object)
Subscribers

Returns a list of current subscribers for monitoring and tracking purposes, not for invoking Flow.Subscriber methods on the subscribers.

ThresholdClass
ThresholdType

Methods

Clone()

Creates and returns a copy of this object.

(Inherited from Object)
Close()

Unless already closed, issues Flow.Subscriber#onComplete() onComplete signals to current subscribers, and disallows subsequent attempts to publish.

CloseExceptionally(Throwable)

Unless already closed, issues Flow.Subscriber#onError(Throwable) onError signals to current subscribers with the given error, and disallows subsequent attempts to publish.

Consume(IConsumer)

Processes all published items using the given Consumer function.

Dispose() (Inherited from Object)
Dispose(Boolean) (Inherited from Object)
Equals(Object)

Indicates whether some other object is "equal to" this one.

(Inherited from Object)
EstimateMaximumLag()

Returns an estimate of the maximum number of items produced but not yet consumed among all current subscribers.

EstimateMinimumDemand()

Returns an estimate of the minimum number of items requested (via Flow.Subscription#request(long) request) but not yet produced, among all current subscribers.

GetHashCode()

Returns a hash code value for the object.

(Inherited from Object)
IsSubscribed(Flow+ISubscriber)
JavaFinalize()

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

(Inherited from Object)
Notify()

Wakes up a single thread that is waiting on this object's monitor.

(Inherited from Object)
NotifyAll()

Wakes up all threads that are waiting on this object's monitor.

(Inherited from Object)
Offer(Object, IBiPredicate)

Publishes the given item, if possible, to each current subscriber by asynchronously invoking its Flow.Subscriber#onNext(Object) onNext method.

Offer(Object, Int64, TimeUnit, IBiPredicate)

Publishes the given item, if possible, to each current subscriber by asynchronously invoking its Flow.Subscriber#onNext(Object) onNext method, blocking while resources for any subscription are unavailable, up to the specified timeout or until the caller thread is interrupted, at which point the given handler (if non-null) is invoked, and if it returns true, retried once.

SetHandle(IntPtr, JniHandleOwnership)

Sets the Handle property.

(Inherited from Object)
Submit(Object)

Publishes the given item to each current subscriber by asynchronously invoking its Flow.Subscriber#onNext(Object) onNext method, blocking uninterruptibly while resources for any subscriber are unavailable.

Subscribe(Flow+ISubscriber)
ToArray<T>() (Inherited from Object)
ToString()

Returns a string representation of the object.

(Inherited from Object)
UnregisterFromRuntime() (Inherited from Object)
Wait()

Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>.

(Inherited from Object)
Wait(Int64, Int32)

Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>, or until a certain amount of real time has elapsed.

(Inherited from Object)
Wait(Int64)

Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>, or until a certain amount of real time has elapsed.

(Inherited from Object)

Explicit Interface Implementations

IJavaPeerable.Disposed() (Inherited from Object)
IJavaPeerable.DisposeUnlessReferenced() (Inherited from Object)
IJavaPeerable.Finalized() (Inherited from Object)
IJavaPeerable.JniManagedPeerState (Inherited from Object)
IJavaPeerable.SetJniIdentityHashCode(Int32) (Inherited from Object)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) (Inherited from Object)
IJavaPeerable.SetPeerReference(JniObjectReference) (Inherited from Object)

Extension Methods

JavaCast<TResult>(IJavaObject)

Performs an Android runtime-checked type conversion.

JavaCast<TResult>(IJavaObject)
GetJniTypeName(IJavaPeerable)

Applies to