action/api/src/main/java/io/knotx/fragments/action/api/invoker/ActionInvoker.java
/**
   * Executes the given action with the given context. Measures execution time and handles errors
   * captured via ReactiveX interface.
   * <p>
   * The downstream <b>will receive a succeeded <code>Single</code></b> with an
   * <code>ActionInvocation</code> object with a delivered <code>FragmentResult</code> and
   * <code>duration</code> in ms in these scenarios:
   * <table>
   *   <caption>Happy path execution cases</caption>
   *    <tr><td><b>Action</b></td><td><b>ResultHandler</b></td><td><b>AsyncResult</b></td><td><b>FragmentResult</b></td></tr>
   *    <tr><td>returns</td><td>called (eventually)</td><td>succeeded</td><td>+</td></tr>
   *    <tr><td>returns</td><td>called (eventually)</td><td>succeeding Future (eventually)</td><td>+</td></tr>
   * </table>
   * <i>Please note that only the first case is considered valid in Knot.x environment.</i>
   * To conform to this standard, please use {@link io.knotx.fragments.action.api.SyncAction SyncAction}, {@link io.knotx.fragments.action.api.FutureAction FutureAction} or {@link io.knotx.fragments.action.api.SingleAction SingleAction}.
   * <p>
   * The downstream <b>will also receive a succeeded <code>Single</code></b> with an
   * <code>ActionInvocation</code> object representing a failed invocation, containing exception details, exception-like <code>FragmentResult</code> with original <code>FragmentContext</code> and <code>duration</code> in ms in these scenarios:
   * <table>
   *   <caption>Failed ActionInvocation return cases</caption>
   *   <tr><td><b>Action</b></td><td><b>ResultHandler</b></td><td><b>AsyncResult</b></td><td><b>FragmentResult</b></td></tr>
   *   <tr><td>returns</td><td>called (eventually)</td><td>failed</td><td>-</td></tr>
   *   <tr><td>returns</td><td>called (eventually)</td><td>succeeded</td><td>null</td></tr>
   *   <tr><td>returns</td><td>called (eventually)</td><td>failing Future (eventually)</td><td>-</td></tr>
   *   <tr><td>returns</td><td>called (eventually)</td><td>succeeding Future (eventually)</td><td>null</td></tr>
   *   <tr><td>returns</td><td>called (eventually)</td><td>unresolved yet, not Future</td><td>*</td></tr>
   *   <tr><td>returns</td><td>called (eventually)</td><td>null</td><td>-</td></tr>
   *   <tr><td>throws</td><td>not called</td><td>-</td><td>-<td></tr>
   *   <tr><td>null</td><td>not called</td><td>-</td><td>-<td></tr>
   * </table>
   * <i>Please note that only the first and second cases are considered valid in Knot.x environment.</i>
   * <p>
   * The downstream <b>will halt forever</b> (unless terminated by an external timeout) in these scenarios:
   * <table>
   *   <caption>Hanging cases</caption>
   *   <tr><td><b>Action</b></td><td><b>ResultHandler</b></td><td><b>AsyncResult</b></td><td><b>FragmentResult</b></td></tr>
   *   <tr><td>returns</td><td>not called</td><td>-</td><td>-</td></tr>
   *   <tr><td>returns</td><td>called (eventually)</td><td>Future (never resolved)</td><td>-</td></tr>
   * </table>
   * <p>
   * <i>Please note that only the first case is considered valid in Knot.x environment.</i>
   * <p>
   * There is also a possibility of a broken ReactiveX stream in case of a fatal VM exception.
   * In this case, the thread executing the stream will be propagated with an exception instead of populating it downstream.
   * This is very unlikely to happen. For reference, see {@link io.reactivex.exceptions.Exceptions#throwIfFatal(Throwable)}
   *
   * @param action  the action to be executed
   * @param context the context with which action will be applied.
   * @return Single representing invocation, that either succeeds or halts.
   */
Executes the given action with the given context. Measures execution time and handles errors
captured via ReactiveX interface.

The downstream will receive a succeeded Single with an
ActionInvocation object with a delivered FragmentResult and
duration in ms in these scenarios:

Happy path execution cases
ActionResultHandlerAsyncResultFragmentResult
returnscalled (eventually)succeeded+
returnscalled (eventually)succeeding Future (eventually)+

Please note that only the first case is considered valid in Knot.x environment.
To conform to this standard, please use  io.knotx.fragments.action.api.SyncAction SyncAction,  io.knotx.fragments.action.api.FutureAction FutureAction or  io.knotx.fragments.action.api.SingleAction SingleAction.

@param action  the action to be executed
@param context the context with which action will be applied.
@return Single representing invocation, that either succeeds or halts.
Executes the given action with the given context . Measures execution time and handles errors captured via ReactiveX interface . The downstream will receive a succeeded Single with an ActionInvocation object with a delivered FragmentResult and duration in ms in these scenarios : Happy path execution cases ActionResultHandlerAsyncResultFragmentResult returnscalled ( eventually ) succeeded + returnscalled ( eventually ) succeeding Future ( eventually ) + Please note that only the first case is considered valid in Knot . x environment . To conform to this standard please use io . knotx . fragments . action . api . SyncAction SyncAction io . knotx . fragments . action . api . FutureAction FutureAction or io . knotx . fragments . action . api . SingleAction SingleAction . @param action the action to be executed @param context the context with which action will be applied . @return Single representing invocation that either succeeds or halts .
public static Single<ActionInvocation> rxApply(Action action, FragmentContext context) {
    Timer timer = new Timer();
    return rxApply(action, context, timer)
        .onErrorReturn(e -> ActionInvocation.exception(timer.duration(), e, context));
  }
public static Single < ActionInvocation > rxApply ( Action action , FragmentContext context ) { Timer timer = new Timer ( ) ; return rxApply ( action , context , timer ) . onErrorReturn ( e -> ActionInvocation . exception ( timer . duration ( ) , e , context ) ) ; }
Executes the given action with the given context.
Executes the given action with the given context .