All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.jersey.internal.jsr166.Flow Maven / Gradle / Ivy

Go to download

A bundle project producing JAX-RS RI bundles. The primary artifact is an "all-in-one" OSGi-fied JAX-RS RI bundle (jaxrs-ri.jar). Attached to that are two compressed JAX-RS RI archives. The first archive (jaxrs-ri.zip) consists of binary RI bits and contains the API jar (under "api" directory), RI libraries (under "lib" directory) as well as all external RI dependencies (under "ext" directory). The secondary archive (jaxrs-ri-src.zip) contains buildable JAX-RS RI source bundle and contains the API jar (under "api" directory), RI sources (under "src" directory) as well as all external RI dependencies (under "ext" directory). The second archive also contains "build.xml" ANT script that builds the RI sources. To build the JAX-RS RI simply unzip the archive, cd to the created jaxrs-ri directory and invoke "ant" from the command line.

There is a newer version: 3.1.6
Show newest version
/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

package org.glassfish.jersey.internal.jsr166;

/**
 * Interrelated interfaces and static methods for establishing
 * flow-controlled components in which {@link Publisher Publishers}
 * produce items consumed by one or more {@link Subscriber
 * Subscribers}, each managed by a {@link Subscription
 * Subscription}.
 *
 * 

These interfaces correspond to the reactive-streams * specification. They apply in both concurrent and distributed * asynchronous settings: All (seven) methods are defined in {@code * void} "one-way" message style. Communication relies on a simple form * of flow control (method {@link Subscription#request}) that can be * used to avoid resource management problems that may otherwise occur * in "push" based systems. * *

Examples. A {@link Publisher} usually defines its own * {@link Subscription} implementation; constructing one in method * {@code subscribe} and issuing it to the calling {@link * Subscriber}. It publishes items to the subscriber asynchronously, * normally using an {@link java.util.concurrent.Executor}. For example, here is a very * simple publisher that only issues (when requested) a single {@code * TRUE} item to a single subscriber. Because the subscriber receives * only a single item, this class does not use buffering and ordering * control required in most implementations (for example {@link * SubmissionPublisher}). * *

 {@code
 * class OneShotPublisher implements Publisher {
 *   private final ExecutorService executor = ForkJoinPool.commonPool(); // daemon-based
 *   private boolean subscribed; // true after first subscribe
 *   public synchronized void subscribe(Subscriber subscriber) {
 *     if (subscribed)
 *        subscriber.onError(new IllegalStateException()); // only one allowed
 *     else {
 *       subscribed = true;
 *       subscriber.onSubscribe(new OneShotSubscription(subscriber, executor));
 *     }
 *   }
 *   static class OneShotSubscription implements Subscription {
 *     private final Subscriber subscriber;
 *     private final ExecutorService executor;
 *     private Future future; // to allow cancellation
 *     private boolean completed;
 *     OneShotSubscription(Subscriber subscriber,
 *                         ExecutorService executor) {
 *       this.subscriber = subscriber;
 *       this.executor = executor;
 *     }
 *     public synchronized void request(long n) {
 *       if (n != 0 && !completed) {
 *         completed = true;
 *         if (n < 0) {
 *           IllegalArgumentException ex = new IllegalArgumentException();
 *           executor.execute(() -> subscriber.onError(ex));
 *         } else {
 *           future = executor.submit(() -> {
 *             subscriber.onNext(Boolean.TRUE);
 *             subscriber.onComplete();
 *           });
 *         }
 *       }
 *     }
 *     public synchronized void cancel() {
 *       completed = true;
 *       if (future != null) future.cancel(false);
 *     }
 *   }
 * }}
* *

A {@link Subscriber} arranges that items be requested and * processed. Items (invocations of {@link Subscriber#onNext}) are * not issued unless requested, but multiple items may be requested. * Many Subscriber implementations can arrange this in the style of * the following example, where a buffer size of 1 single-steps, and * larger sizes usually allow for more efficient overlapped processing * with less communication; for example with a value of 64, this keeps * total outstanding requests between 32 and 64. * Because Subscriber method invocations for a given {@link * Subscription} are strictly ordered, there is no need for these * methods to use locks or volatiles unless a Subscriber maintains * multiple Subscriptions (in which case it is better to instead * define multiple Subscribers, each with its own Subscription). * *

 {@code
 * class SampleSubscriber implements Subscriber {
 *   final Consumer consumer;
 *   Subscription subscription;
 *   final long bufferSize;
 *   long count;
 *   SampleSubscriber(long bufferSize, Consumer consumer) {
 *     this.bufferSize = bufferSize;
 *     this.consumer = consumer;
 *   }
 *   public void onSubscribe(Subscription subscription) {
 *     long initialRequestSize = bufferSize;
 *     count = bufferSize - bufferSize / 2; // re-request when half consumed
 *     (this.subscription = subscription).request(initialRequestSize);
 *   }
 *   public void onNext(T item) {
 *     if (--count <= 0)
 *       subscription.request(count = bufferSize - bufferSize / 2);
 *     consumer.accept(item);
 *   }
 *   public void onError(Throwable ex) { ex.printStackTrace(); }
 *   public void onComplete() {}
 * }}
* *

The default value of {@link #defaultBufferSize} may provide a * useful starting point for choosing request sizes and capacities in * Flow components based on expected rates, resources, and usages. * Or, when flow control is never needed, a subscriber may initially * request an effectively unbounded number of items, as in: * *

 {@code
 * class UnboundedSubscriber implements Subscriber {
 *   public void onSubscribe(Subscription subscription) {
 *     subscription.request(Long.MAX_VALUE); // effectively unbounded
 *   }
 *   public void onNext(T item) { use(item); }
 *   public void onError(Throwable ex) { ex.printStackTrace(); }
 *   public void onComplete() {}
 *   void use(T item) { ... }
 * }}
* * @author Doug Lea * @since 9 */ public final class Flow { private Flow() {} // uninstantiable /** * A producer of items (and related control messages) received by * Subscribers. Each current {@link Subscriber} receives the same * items (via method {@code onNext}) in the same order, unless * drops or errors are encountered. If a Publisher encounters an * error that does not allow items to be issued to a Subscriber, * that Subscriber receives {@code onError}, and then receives no * further messages. Otherwise, when it is known that no further * messages will be issued to it, a subscriber receives {@code * onComplete}. Publishers ensure that Subscriber method * invocations for each subscription are strictly ordered in happens-before * order. * *

Publishers may vary in policy about whether drops (failures * to issue an item because of resource limitations) are treated * as unrecoverable errors. Publishers may also vary about * whether Subscribers receive items that were produced or * available before they subscribed. * * @param the published item type */ @FunctionalInterface public static interface Publisher { /** * Adds the given Subscriber if possible. If already * subscribed, or the attempt to subscribe fails due to policy * violations or errors, the Subscriber's {@code onError} * method is invoked with an {@link IllegalStateException}. * Otherwise, the Subscriber's {@code onSubscribe} method is * invoked with a new {@link Subscription}. Subscribers may * enable receiving items by invoking the {@code request} * method of this Subscription, and may unsubscribe by * invoking its {@code cancel} method. * * @param subscriber the subscriber * @throws NullPointerException if subscriber is null */ public void subscribe(Subscriber subscriber); } /** * A receiver of messages. The methods in this interface are * invoked in strict sequential order for each {@link * Subscription}. * * @param the subscribed item type */ public static interface Subscriber { /** * Method invoked prior to invoking any other Subscriber * methods for the given Subscription. If this method throws * an exception, resulting behavior is not guaranteed, but may * cause the Subscription not to be established or to be cancelled. * *

Typically, implementations of this method invoke {@code * subscription.request} to enable receiving items. * * @param subscription a new subscription */ public void onSubscribe(Subscription subscription); /** * Method invoked with a Subscription's next item. If this * method throws an exception, resulting behavior is not * guaranteed, but may cause the Subscription to be cancelled. * * @param item the item */ public void onNext(T item); /** * Method invoked upon an unrecoverable error encountered by a * Publisher or Subscription, after which no other Subscriber * methods are invoked by the Subscription. If this method * itself throws an exception, resulting behavior is * undefined. * * @param throwable the exception */ public void onError(Throwable throwable); /** * Method invoked when it is known that no additional * Subscriber method invocations will occur for a Subscription * that is not already terminated by error, after which no * other Subscriber methods are invoked by the Subscription. * If this method throws an exception, resulting behavior is * undefined. */ public void onComplete(); } /** * Message control linking a {@link Publisher} and {@link * Subscriber}. Subscribers receive items only when requested, * and may cancel at any time. The methods in this interface are * intended to be invoked only by their Subscribers; usages in * other contexts have undefined effects. */ public static interface Subscription { /** * Adds the given number {@code n} of items to the current * unfulfilled demand for this subscription. If {@code n} is * negative, the Subscriber will receive an {@code onError} * signal with an {@link IllegalArgumentException} argument. * Otherwise, the Subscriber will receive up to {@code n} * additional {@code onNext} invocations (or fewer if * terminated). * * @param n the increment of demand; a value of {@code * Long.MAX_VALUE} may be considered as effectively unbounded */ public void request(long n); /** * Causes the Subscriber to (eventually) stop receiving * messages. Implementation is best-effort -- additional * messages may be received after invoking this method. * A cancelled subscription need not ever receive an * {@code onComplete} or {@code onError} signal. */ public void cancel(); } /** * A component that acts as both a Subscriber and Publisher. * * @param the subscribed item type * @param the published item type */ public static interface Processor extends Subscriber, Publisher { } static final int DEFAULT_BUFFER_SIZE = 256; /** * Returns a default value for Publisher or Subscriber buffering, * that may be used in the absence of other constraints. * * @implNote * The current value returned is 256. * * @return the buffer size value */ public static int defaultBufferSize() { return DEFAULT_BUFFER_SIZE; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy