Class ReactiveValue<T>

  • Type Parameters:
    T - type of the result carried by this ReactiveValue

    @DraftDocs("link to reactive value/output articles")
    public class ReactiveValue<T>
    extends Object
    Container for output of reactive computation consisting of return value, exception, and reactive blocking flag. ReactiveValue can be split into its constituent components by calling result(), exception(), and blocking(). It can be recreated from these components by calling ReactiveValue(Object, Throwable, boolean) or some other constructor. ReactiveValue is immutable.

    Reactive code usually takes the form of a method and communicates its output like a method, i.e. via return value or an exception. Reactive code may additionally signal reactive blocking by calling CurrentReactiveScope.block(). Return value, exception, and signaling of reactive blocking constitutes implicit output of reactive computation. ReactiveValue offers an explicit representation of the same. Conversion between explicit and implicit representations is performed by methods get() and capture(Supplier).

    ReactiveValue does not carry reactive dependencies. Use ReactiveScope for that.

    See Also:
    ReactiveVariable, ReactiveScope
    • Constructor Detail

      • ReactiveValue

        public ReactiveValue​(T result,
                             Throwable exception,
                             boolean blocking)
        Constructs new ReactiveValue from return value, exception, and reactive blocking flag. Only one of result and exception can be non-null. The parameters can be later retrieved via result(), exception(), and blocking().
        Parameters:
        result - component representing return value of reactive computation that can be later retrieved via result()
        exception - component representing exception thrown by reactive computation that can be later retrieved via exception()
        blocking - true if the constructed ReactiveValue should represent blocking reactive computation, false otherwise
        Throws:
        IllegalArgumentException - if both result and exception are non-null
        See Also:
        capture(Supplier)
      • ReactiveValue

        public ReactiveValue​(T result)
        Constructs new ReactiveValue from return value. The new ReactiveValue represents reactive computation that successfully completed without blocking. The ReactiveValue will have null exception() and false blocking() flag.
        Parameters:
        result - return value of the reactive computation the new ReactiveValue represents
        See Also:
        ReactiveValue(Object, Throwable, boolean)
      • ReactiveValue

        public ReactiveValue​(Throwable exception)
        Constructs new ReactiveValue from exception. The new ReactiveValue represents reactive computation that threw an exception without blocking. The ReactiveValue will have null result() and false blocking() flag.
        Parameters:
        exception - exception thrown by the reactive computation the new ReactiveValue represents
        See Also:
        ReactiveValue(Object, Throwable, boolean)
      • ReactiveValue

        public ReactiveValue​(T result,
                             boolean blocking)
        Constructs new ReactiveValue from return value and blocking flag. The new ReactiveValue represents reactive computation that successfully completed and possibly signaled blocking. The ReactiveValue will have null exception().
        Parameters:
        result - return value of the reactive computation the new ReactiveValue represents
        blocking - true if the constructed ReactiveValue should represent blocking reactive computation, false otherwise
        See Also:
        ReactiveValue(Object, Throwable, boolean)
      • ReactiveValue

        public ReactiveValue​(Throwable exception,
                             boolean blocking)
        Constructs new ReactiveValue from exception and blocking flag. The new ReactiveValue represents reactive computation that threw an exception and possibly signaled blocking. The ReactiveValue will have null result().
        Parameters:
        exception - exception thrown by the reactive computation the new ReactiveValue represents
        blocking - true if the constructed ReactiveValue should represent blocking reactive computation, false otherwise
        See Also:
        ReactiveValue(Object, Throwable, boolean)
    • Method Detail

      • result

        public T result()
        Gets the return value component of this ReactiveValue. Only one of result() and exception() can be non-null.
        Returns:
        return value component of ReactiveValue
        See Also:
        exception(), get()
      • exception

        public Throwable exception()
        Gets the exception component of this ReactiveValue. Only one of result() and exception() can be non-null.
        Returns:
        exception component of ReactiveValue
        See Also:
        result(), get()
      • blocking

        public boolean blocking()
        Gets the reactive blocking flag from this ReactiveValue. Blocking flag is set if this ReactiveValue represents output of reactive computation that signaled blocking during its execution by calling CurrentReactiveScope.block().
        Returns:
        true if this ReactiveValue represents output of blocking reactive computation, false otherwise
        See Also:
        get(), Reactive blocking
      • capture

        public static <T> ReactiveValue<T> capture​(Supplier<T> supplier)
        Captures implicit reactive output of provided Supplier and returns it encapsulated in new ReactiveValue. If the supplier throws, returned ReactiveValue will have exception() set to the caught exception. Otherwise the ReactiveValue will have result() set to value returned from the supplier.

        If the supplier reactively blocks by calling CurrentReactiveScope.block(), blocking() flag will be set on the returned ReactiveValue. This method obtains blocking flag by calling CurrentReactiveScope.blocked() after calling the supplier, which means the returned ReactiveValue will have blocking() flag set also if the current ReactiveScope was already blocked by the time this method was called. This is reasonable behavior, because the supplier might be itself derived from information produced by blocking operations executed earlier during the current reactive computation, which means that supplier's output cannot be trusted to be non-blocking.

        If there is no current ReactiveScope, i.e. ReactiveScope.current() returns null, this method creates temporary ReactiveScope and executes the supplier in it, so that blocking flag can be captured. This is particularly useful in unit tests.

        Type Parameters:
        T - type of value returned by the supplier
        Parameters:
        supplier - reactive code to execute
        Returns:
        ReactiveValue encapsulating implicit reactive output of the supplier
        See Also:
        ReactiveValue(Object, Throwable, boolean)
      • equals

        public boolean equals​(Object obj)
        Compares this ReactiveValue to another object for equality. ReactiveValue can only equal another ReactiveValue. Two ReactiveValue instances are equal if their result(), exception(), and blocking() flags are equal. Value equality is used for both result() and exception(). Two exceptions are equal when their stringified form (including stack trace and causes) compares equal.

        Full value equality checking may be expensive or even undesirable. Use same(ReactiveValue) to compute shallow reference equality.

        Overrides:
        equals in class Object
        Parameters:
        obj - object to compare this ReactiveValue to or null
        Returns:
        true if the objects compare equal, false otherwise
        See Also:
        same(ReactiveValue), hashCode()
      • hashCode

        public int hashCode()
        Computes hash code of this ReactiveValue. Hash code is calculated in such a way that if two ReactiveValue instances are equal as checked by equals(Object), then their hash codes are equal too. This makes ReactiveValue usable as a key in a Map.

        Both result() and exception() are included in hash code calculation. Exceptions are hashed in such a way that two exceptions with the same stringified form (including stack traces and causes) will have the same hash code.

        Overrides:
        hashCode in class Object
        Returns:
        hash code of this ReactiveValue
        See Also:
        equals(Object)
      • same

        public boolean same​(ReactiveValue<?> other)
        Checks reference equality between two ReactiveValue instances. Another ReactiveValue is reference-equal to this instance according to this method if it is not null and its result(), exception(), and blocking() components are all reference-equal to corresponding components of this ReactiveValue.

        This method is useful when equals(Object) would be too expensive or where reference equality is desirable.

        Parameters:
        other - ReactiveValue to compare this instance to or null
        Returns:
        true if the two ReactiveValue instances are reference-equal, false otherwise
        See Also:
        equals(Object)
      • toString

        public String toString()
        Returns a string representation of this ReactiveValue. The returned string is suitable for debug output and includes string representation of result() or exception() as well as indication whether the ReactiveValue is blocking().
        Overrides:
        toString in class Object
        Returns:
        string representation of this ReactiveValue