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

io.vertx.resourceadapter.impl.VertxPlatformFactory Maven / Gradle / Ivy

There is a newer version: 3.9.8
Show newest version
package io.vertx.resourceadapter.impl;

import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.impl.ConcurrentHashSet;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A singleton factory to start a clustered Vert.x platform.
 *
 * One clusterPort/clusterHost pair matches one Vert.x platform.
 *
 * @author Lin Gao 
 *
 */
public class VertxPlatformFactory {

  private static final Logger log = Logger.getLogger(VertxPlatformFactory.class
      .getName());

  private static final VertxPlatformFactory INSTANCE = new VertxPlatformFactory();

  /**
   * All Vert.x platforms.
   *
   */
  private final Map vertxPlatforms = new ConcurrentHashMap();

  /**
   * All Vert.x holders
   */
  private final Set vertxHolders = new ConcurrentHashSet();

  private VertxPlatformFactory() {
  }

  public static VertxPlatformFactory instance() {
    return INSTANCE;
  }

  /**
   * Creates a Vertx if one is not started yet.
   *
   * @param config
   *          the configuration to start a vertx
   * @param lifecyleListener
   *          the vertx lifecycle listener
   */
  public synchronized void getOrCreateVertx(
      final VertxPlatformConfiguration config, final VertxListener listener) {

    Vertx vertx = vertxPlatforms.get(config.getVertxPlatformIdentifier());

    if (vertx != null) {
      listener.whenReady(vertx);
      return;
    }

    VertxOptions options = new VertxOptions();
    options.setClustered(config.isClustered());
    options.setClusterHost(config.getClusterHost());
    options.setClusterPort(config.getClusterPort());

    CountDownLatch latch = new CountDownLatch(1);
    Vertx.clusteredVertx(options, ar -> {
      try {
        if (ar.succeeded()) {
          log.log(Level.INFO, "Acquired Vert.x platform.");
          listener.whenReady(ar.result());
          vertxPlatforms.put(config.getVertxPlatformIdentifier(), ar.result());
        } else {
          throw new RuntimeException("Could not acquire Vert.x platform.",
              ar.cause());
        }
      } finally {
        latch.countDown();
      }
    });

    try {
      if (!latch.await(config.getTimeout(), TimeUnit.MILLISECONDS)) {
        log.log(Level.SEVERE, "Could not acquire Vert.x platform in interval.");
        throw new RuntimeException(
            "Could not acquire Vert.x platform in interval");
      }
    } catch (Exception ignore) {
    }
  }

  /**
   * Adds VertxHolder to be recorded.
   *
   * @param holder
   *          the VertxHolder
   */
  public void addVertxHolder(VertxHolder holder) {

    if (vertxPlatforms.containsValue(holder.getVertx())) {
      if (!this.vertxHolders.contains(holder)) {
        log.log(Level.INFO, "Adding Vertx Holder: " + holder);
        this.vertxHolders.add(holder);
      } else {
        log.log(Level.WARNING, "Vertx Holder: " + holder
            + " has been added already.");
      }
    } else {
      log.log(Level.SEVERE, "Vertx Holder: " + holder
          + " is out of management.");
    }
  }

  /**
   * Removes the VertxHolder from recorded.
   *
   * @param holder
   *          the VertxHolder
   */
  public void removeVertxHolder(VertxHolder holder) {

    if (this.vertxHolders.contains(holder)) {
      log.log(Level.INFO, "Removing Vertx Holder: " + holder);
      this.vertxHolders.remove(holder);
    } else {
      log.log(Level.SEVERE, "Vertx Holder: " + holder
          + " is out of management.");
    }
  }

  /**
   * Stops the Vert.x Platform Manager and removes it from cache.
   *
   * @param config
   */
  public void stopPlatformManager(VertxPlatformConfiguration config) {

    Vertx vertx = this.vertxPlatforms.get(config.getVertxPlatformIdentifier());
    if (vertx != null && isVertxHolded(vertx)) {
      log.log(Level.INFO,
          "Stopping Vert.x: " + config.getVertxPlatformIdentifier());
      vertxPlatforms.remove(config.getVertxPlatformIdentifier());
      stopVertx(vertx);
    }
  }

  private boolean isVertxHolded(Vertx vertx) {
    for (VertxHolder holder : this.vertxHolders) {
      if (vertx.equals(holder.getVertx())) {
        return true;
      }
    }
    return false;
  }

  /**
   * Stops all started Vert.x platforms.
   *
   * Clears all vertx holders.
   */
  public void closeAllPlatforms() {

    log.log(Level.FINEST, "Closing all Vert.x instances");
    try {

      for (Map.Entry entry : this.vertxPlatforms.entrySet()) {
        stopVertx(entry.getValue());
      }
      vertxPlatforms.clear();
      vertxHolders.clear();

    } catch (Exception e) {
      log.log(Level.SEVERE, "Error closing Vert.x instance", e.getCause());
    }
  }

  private void stopVertx(Vertx vertx) {

    CountDownLatch latch = new CountDownLatch(1);
    vertx.close(ar -> {
      try {

        if (ar.succeeded()) {
          log.log(Level.INFO, "Closed Vert.x platform");
        } else {
          log.log(Level.WARNING, "Could not close Vert.x platform.",
              ar.cause());
        }
      } finally {
        latch.countDown();
      }
    });

    try {
      if (!latch.await(30, TimeUnit.SECONDS)) {
        log.log(Level.WARNING, "Could not close Vert.x platform");
      }
    } catch (Exception ignore) {
    }

  }

  /**
   * The Listener to monitor whether the embedded vert.x runtime is ready.
   *
   */
  public interface VertxListener {

    /**
     * When vertx is ready, maybe just started, or have been started already.
     *
     * NOTE: can't call vertxPlatforms related methods within this callback
     * method, which will cause infinite waiting.
     *
     * @param vertx
     *          the Vert.x
     */
    void whenReady(Vertx vertx);

  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy