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

io.vlingo.reactivestreams.Source Maven / Gradle / Ivy

There is a newer version: 1.7.5
Show newest version
// Copyright © 2012-2020 VLINGO LABS. All rights reserved.
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL
// was not distributed with this file, You can obtain
// one at https://mozilla.org/MPL/2.0/.

package io.vlingo.reactivestreams;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Supplier;

import io.vlingo.common.Completes;
import io.vlingo.reactivestreams.source.IterableSource;
import io.vlingo.reactivestreams.source.LongRangeSource;
import io.vlingo.reactivestreams.source.SupplierSource;

/**
 * The upstream source of a {@code Stream} that provides {@code Element} of
 * next available value(s), or indicates termination of such values.
 * 

* WARNING: *

* A {@code Source} is polled asynchronously by a {@code StreamPublisher}. * The {@code StreamPublisher} uses a {@link io.vlingo.common.Scheduler} * to determine the time interval between polling, and could assume the * rapid answer of the next element(s) or empty. Consider possible flaws * in such a design: *

* (1) Latency in {@code next()} and {@code next(int index)} may cause * publish conflicts given that the subsequent {@code intervalSignal()} is * delivered and its {@code next()} or {@code next(int index)} completes * before the previous publish completes. This would no doubt cause races * in any managed subscription instances. *

* (2) Latency in {@code next()} and {@code next(int index)} may also cause * eventual {@code OutOfMemoryException} due to {@code intervalSignal()} * messages growing the {@code StreamPublisher}'s mailbox faster than * it can process them. *

* In order to avoid this situation {@code isSlow()} is provided. If * {@code isSlow()} answers {@code true} the {@code StreamPublisher} * will reschedule its given time interval following the completion * of each {@code next()}/{@code next(int index)} and publish pair. * Although doubtful, this could tax the scheduler while preventing * the above two potential flaws. *

* If {@code isSlow()} answers {@code false} the {@code StreamPublisher} * will schedule a recurring time interval, which is done only once. * * @param the type produced by the {@code Source} */ public interface Source { /** * Answer a new empty {@code Source}. * @param the type of Source elements * @return {@code Source} */ @SuppressWarnings({ "unchecked", "rawtypes" }) static Source empty() { return new IterableSource(new ArrayList<>(0), false); } /** * Answer a new {@code Source} with the static * number of {@code elements}. * @param elements the T typed element(s) provided by the new {@code Source} * @param the type of Source elements * @return {@code Source} */ @SafeVarargs @SuppressWarnings({ "unchecked", "rawtypes" }) static Source only(final T... elements) { return new IterableSource(Arrays.asList(elements), false); } /** * Answer a new {@code Source} with element(s) to be provided between * {@code startInclusive} and {@code endExclusive}. The {@code Source} is * non-slow. * @param startInclusive the long start of the range, inclusive * @param endExclusive the long end of the range, exclusive * @return {@code Source} */ static Source rangeOf(final long startInclusive, final long endExclusive) { return new LongRangeSource(startInclusive, endExclusive); } /** * Answer the number of {@code elements}, or if {@code elements} is out of bounds, * answer {@code Long.MAX_VALUE}. * @param elements the long number of elements, which may be in bounds or out of bounds * @return long */ static long orElseMaximum(final long elements) { if (elements < 0) { return Long.MAX_VALUE; } return elements; } /** * Answer the number of {@code elements}, or if {@code elements} is out of bounds, * answer {@code 0}. * @param elements the long number of elements, which may be in bounds or out of bounds * @return long */ static long orElseMinimum(final long elements) { if (elements < 0) { return 0; } return elements; } /** * Answer a new {@code Source} with element(s) to be provided * by the {@code Iterable}. The {@code Source} is created * as non-slow. * @param iterable the {@code Iterable} providing element(s) for the new {@code Source} * @param the type of Source elements * @return {@code Source} */ static Source with(final Iterable iterable) { return with(iterable, false); } /** * Answer a new {@code Source} with element(s) to be provided by the * {@code Iterable}, which may or may not be a {@code slowIterable} * @param iterable the {@code Iterable} providing element(s) for the new {@code Source} * @param slowIterable the boolean indicating whether or not the iterable is slow * @param the type of Source elements * @return {@code Source} */ @SuppressWarnings({ "unchecked", "rawtypes" }) static Source with(final Iterable iterable, final boolean slowIterable) { return new IterableSource(iterable, slowIterable); } /** * Answer a new {@code Source} with elements to be provided by the {@code Supplier}. * The {@code Source} is created created as non-slow. * @param supplier the {@code Supplier} providing element(s) for the new {@code Source} * @param the type of Source elements * @return {@code Source} */ static Source with(final Supplier supplier) { return with(supplier, false); } /** * Answer a new {@code Source} with elements to be provided by the {@code Supplier}, * which may or may not be a {@code slowSupplier}. * @param supplier the {@code Supplier} providing element(s) for the new {@code Source} * @param slowSupplier the boolean indicating whether or not the supplier is slow * @param the type of Source elements * @return {@code Source} */ @SuppressWarnings({ "unchecked", "rawtypes" }) static Source with(final Supplier supplier, final boolean slowSupplier) { return new SupplierSource(supplier, slowSupplier); } /** * Answers the next element(s) as a {@code Completes>}, which has a * zero length {@code values} when the next element is not immediately available. * Answering the zero length {@code Completes>.value} is to prevent blocking. * @return {@code Completes>} */ Completes> next(); /** * Answers the next {@code maximumElements} as a {@code Completes>}, which has a * zero length {@code values} when the next element is not immediately available. * Answering the zero length {@code Completes>.value} is to prevent blocking. * @param maximumElements the int maximum number of elements to answer * @return {@code Completes>} */ Completes> next(final int maximumElements); /** * Answers the next element(s) starting at {@code index} as a {@code Completes>}, * which has a zero length {@code values} when at least the indexed element is not * immediately available. Answering the zero length {@code Completes>.value} * is to prevent blocking. *

* It is recommended to use this method only when the elements are actually * identified by indexes, such as with an ordered collection or log. * * @param index the long index of the element at which to start * @return {@code Completes>} */ Completes> next(final long index); /** * Answers the next {@code maximumElements} starting at {@code index} as a {@code Completes>}, * which has a zero length {@code values} when at least the indexed element is not * immediately available. Answering the zero length {@code Completes>.value} * is to prevent blocking. *

* It is recommended to use this method only when the elements are actually * identified by indexes, such as with an ordered collection or log. * * @param index the long index of the element at which to start * @param maximumElements the int maximum number of elements to answer * @return {@code Completes>} */ Completes> next(final long index, final int maximumElements); /** * Answers whether or not the concrete {@code Source} is subject to * constantly latency or intermittent latency. See the warning in the * above interface documentation. * @return {@code Completes} */ Completes isSlow(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy