Menu
hookless

Class ReactiveLoop<T>

Hookless » API Reference

  • Type Parameters:
    T - Return type of the loop, i.e. type of loop's future(). Specify Void if the loop doesn't return anything.


    public class ReactiveLoop<T>
    extends Object
    A loop that iterates when data changes. Once start() is called, ReactiveLoop runs once and collects dependencies on reactive data during that run. When the reactive data changes, ReactiveLoop runs again and collects new set of dependencies. This continues until either stop(), complete(Object), or fail(Throwable) is called. Started ReactiveLoop is not garbage-collected until it is explicitly stopped by one of these methods.
    Body of the loop can be provided either by overriding run() or by setting body(Runnable). If the loop body throws an exception, it has the same effect as calling fail(Throwable). Loop body is executed by configured executor(), which is compute-optimized by default. Non-default executor(ExecutorService) must be specified if loop body can block.
    It is possible to wait for the loop to complete by monitoring loop's future() (optionally using ReactiveFuture). The kind of termination method used (stop(), complete(Object), or fail(Throwable)) determines final state of the future().
    Thread-safety:
    All methods of this class are thread-safe.
    Reactive programming:
    ReactiveLoop is a reactive computation. It runs when changes are made to reactive data referenced in previous iteration of the loop.
    • Constructor Detail

      • ReactiveLoop

        public ReactiveLoop()
        Creates new ReactiveLoop with empty loop body. Newly created ReactiveLoop can still be garbage-collected until start() is called. It is therefore safe to abandon loops that were not started.
        See Also:
        start()
        Lifecycle:
        ReactiveLoop is not started immediately. Call start() to start the loop.
    • Method Detail

      • body

        public Runnable body()
        Body of the loop specified as Runnable. This is an empty Runnable by default and it is never null.
        Returns:
        Loop's body.
        See Also:
        body(Runnable), run()
        Thread-safety:
        This method can be safely called from multiple threads.
        Reactive programming:
        Loop body is executed in context of reactive computation. Changes in reactive data accessed in the loop body will trigger new iteration of the loop.
      • body

        public ReactiveLoop<T> body(Runnable body)
        Sets new body of the loop. This method is an alternative to overriding run(). Body specified here is ignored if derived class overrides run(). For I/O-bound or time-consuming loop body, non-default ExecutorService must be specified via executor(ExecutorService).
        Parameters:
        body - New loop body.
        Returns:
        this
        Throws:
        NullPointerException - The body parameter is null.
        IllegalStateException - The loop is already started.
        See Also:
        body(), run(), executor(ExecutorService)
        Thread-safety:
        This method can be safely called from multiple threads.
        Reactive programming:
        Loop body is executed in context of reactive computation. Changes in reactive data accessed in the loop body will trigger new iteration of the loop.
        Lifecycle:
        This method can be called only before the loop is started.
      • experimental_weak

        @ExperimentalHooklessApi
        public boolean experimental_weak()
        Experimental API. It WILL be removed in future release.
      • future

        public CompletableFuture<T> future()
        Loop's CompletableFuture that can be queried whether the loop has finished and with what result. When complete(Object) is called, this future completes with the specified result. When fail(Throwable) is called, this future completes exceptionally with the specified exception. When stop() is called, this future completes with null result. ReactiveFuture can be used to query the CompletableFuture as if it is reactive.
        Returns:
        Loop's CompletableFuture.
        See Also:
        stop(), complete(Object), fail(Throwable), ReactiveFuture
        Thread-safety:
        This method can be safely called from multiple threads.
        Reactive programming:
        This method and the returned CompletableFuture are NOT reactive. Reactive behavior can be obtained by wrapping the future in ReactiveFuture.
      • stop

        public ReactiveLoop<T> stop()
        Stops the loop and completes future() with null result. Once stopped, ReactiveLoop becomes eligible for garbage collection.
        Returns:
        this
        See Also:
        start(), future(), complete(Object), fail(Throwable)
        Thread-safety:
        This method can be safely called from multiple threads.
        Lifecycle:
        This method stops the loop. If the loop has been already stopped, this method has no effect. If the loop has not been started yet, it is marked as stopped without ever running a single iteration.
      • complete

        public ReactiveLoop<T> complete(T result)
        Stops the loop and completes future() with the specified result. Once stopped, ReactiveLoop becomes eligible for garbage collection.
        Parameters:
        result - Result with which future() completes.
        Returns:
        this
        See Also:
        start(), future(), stop(), fail(Throwable)
        Thread-safety:
        This method can be safely called from multiple threads.
        Lifecycle:
        This method stops the loop. If the loop has been already stopped, this method has no effect. If the loop has not been started yet, it is marked as stopped without ever running a single iteration.
      • fail

        public ReactiveLoop<T> fail(Throwable exception)
        Stops the loop and completes future() exceptionally with the specified exception. Once stopped, ReactiveLoop becomes eligible for garbage collection.
        Parameters:
        exception - Exception with which future() completes exceptionally.
        Returns:
        this
        See Also:
        start(), future(), complete(Object), stop()
        Thread-safety:
        This method can be safely called from multiple threads.
        Lifecycle:
        This method stops the loop. If the loop has been already stopped, this method has no effect. If the loop has not been started yet, it is marked as stopped without ever running a single iteration.
      • run

        protected void run()
        Loop body. Derived class can override this method to specify loop body, which is an alternative to specifying loop body via body(Runnable). By default, this method just invokes body(). For I/O-bound or time-consuming loop body, non-default ExecutorService must be specified via executor(ExecutorService). This method should never be called directly.
        See Also:
        body(Runnable), executor(ExecutorService)
        Reactive programming:
        Loop body is executed in context of reactive computation. Changes in reactive data accessed in the loop body will trigger new iteration of the loop.