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

org.getshaka.vertx.loom.Coroutine Maven / Gradle / Ivy

package org.getshaka.vertx.loom;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Future;

class Coroutine extends Continuation {
  private final Context vertxContext;
  private final ContinuationScope scope;

  // This is either a Future, or the value of that future.
  // It will always be set & read by the one thread that the
  // Vertx Context is associated with.
  private Object channel = null;

  Coroutine(Context vertxContext, ContinuationScope scope, Runnable program) {
    super(scope, program);
    this.vertxContext = vertxContext;
    this.scope = scope;
  }

  /**
   * Suspends this Coroutine by yielding its Continuation.
   * A handler is added to future, so that when the Future completes,
   * resume() is called, at which point this method returns and the program
   * resumes.
   *
   * Must only ever be called on the VertxContext thread.
   */
  @SuppressWarnings("unchecked")
   A suspend(Future future) {
    channel = future;

    future.onComplete((AsyncResult ar) -> {
      // the Future could be running on a different context, like
      // ForkJoin, or a Postgress Thread Pool. So, we need to make sure
      // resume() is called on the right thread & order via runOnContext.
      vertxContext.runOnContext(voidd -> {
        if (ar.succeeded()) {
          resume(ar.result());
        } else {
          throw new RuntimeException(ar.cause());
        }
      });
    });

    Continuation.yield(scope);
    // When the future completes, it will call resume(). resume() will set
    // channel equal to the Future's resolved value, and continue the continuation,
    // executing the line below..
    return (A) channel;
  }

  /**
   * Resumes this Coroutine, setting its channel.
   */
  void resume(Object v) {
    channel = v;
    run();
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy