net.corda.node.utilities

## Class FiberBox<T>

- net.corda.node.utilities.FiberBox<T>

-     public class FiberBox<T>

  Modelled on ThreadBox, but with support for waiting that is compatible with Quasar Fibers and `class MutableClock`s.

  It supports 3 main operations, all of which operate in a similar context to the locked method of ThreadBox. i.e. in the context of the content.

  - read operations which acquire the associated lock but do not notify any waiters (see readWithDeadline) and is a direct equivalent of ThreadBox.locked.

  - write operations which are the same as read operations but additionally notify any waiters that the content may have changed.

  - readWithDeadline operations acquire the lock and are evaluated repeatedly until they no longer throw any subclass of `exception RetryableException`. Between iterations it will wait until woken by a write or the deadline is reached. It will eventually re-throw a `exception RetryableException` if the deadline passes without any successful iterations.

  The construct also supports `class MutableClock`s so it can cope with artificial progress towards the deadline, for simulations or testing.

  Currently this is intended for use within a node as a simplified way for Oracles to implement subscriptions for changing data by running a flow internally to implement the request handler (see NodeInterestRates.Oracle), which can then effectively relinquish control until the data becomes available. This isn't the most scalable design and is intended to be temporary. In addition, it's enitrely possible to envisage a time when we want public FlowLogic implementations to be able to wait for some condition to become true outside of message send/receive. At that point we may revisit this implementation and indeed the whole model for this, when we understand that requirement more fully.

  TODO: We should consider using a Semaphore or CountDownLatch here to make it a little easier to understand, but it seems as though the current version of Qasar does not support suspending on either of their implementations.

  See Also:
    ThreadBox, Fiber, `class MutableClock`, locked, ThreadBox, ThreadBox.locked, `exception RetryableException`, `exception RetryableException`, `class MutableClock`, NodeInterestRates.Oracle, FlowLogic, Semaphore, CountDownLatch

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `FiberBox(T content, java.util.concurrent.locks.Lock lock)` Modelled on ThreadBox, but with support for waiting that is compatible with Quasar Fibers and `class MutableClock`s.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `<R> R` | `read(kotlin.jvm.functions.Function1<? super T,? extends R> body)`
    `<R> R` | `readWithDeadline(java.time.Clock clock, java.time.Instant deadline, kotlin.jvm.functions.Function1<? super T,? extends R> body)`
    `<R> R` | `write(kotlin.jvm.functions.Function1<? super T,? extends R> body)`

- - ### Constructor Detail

    - #### FiberBox

          public FiberBox(T content,
                          java.util.concurrent.locks.Lock lock)

      Modelled on ThreadBox, but with support for waiting that is compatible with Quasar Fibers and `class MutableClock`s.

      It supports 3 main operations, all of which operate in a similar context to the locked method of ThreadBox. i.e. in the context of the content.

      - read operations which acquire the associated lock but do not notify any waiters (see readWithDeadline) and is a direct equivalent of ThreadBox.locked.

      - write operations which are the same as read operations but additionally notify any waiters that the content may have changed.

      - readWithDeadline operations acquire the lock and are evaluated repeatedly until they no longer throw any subclass of `exception RetryableException`. Between iterations it will wait until woken by a write or the deadline is reached. It will eventually re-throw a `exception RetryableException` if the deadline passes without any successful iterations.

      The construct also supports `class MutableClock`s so it can cope with artificial progress towards the deadline, for simulations or testing.

      Currently this is intended for use within a node as a simplified way for Oracles to implement subscriptions for changing data by running a flow internally to implement the request handler (see NodeInterestRates.Oracle), which can then effectively relinquish control until the data becomes available. This isn't the most scalable design and is intended to be temporary. In addition, it's enitrely possible to envisage a time when we want public FlowLogic implementations to be able to wait for some condition to become true outside of message send/receive. At that point we may revisit this implementation and indeed the whole model for this, when we understand that requirement more fully.

      TODO: We should consider using a Semaphore or CountDownLatch here to make it a little easier to understand, but it seems as though the current version of Qasar does not support suspending on either of their implementations.

      See Also:
        ThreadBox, Fiber, `class MutableClock`, locked, ThreadBox, ThreadBox.locked, `exception RetryableException`, `exception RetryableException`, `class MutableClock`, NodeInterestRates.Oracle, FlowLogic, Semaphore, CountDownLatch

  - ### Method Detail

    - #### readWithDeadline

          public <R> R readWithDeadline(java.time.Clock clock,
                                        java.time.Instant deadline,
                                        kotlin.jvm.functions.Function1<? super T,? extends R> body)

    - #### read

          public <R> R read(kotlin.jvm.functions.Function1<? super T,? extends R> body)

    - #### write

          public <R> R write(kotlin.jvm.functions.Function1<? super T,? extends R> body)