示例#1
0
 private synchronized void checkQuorumWhenAdded(final String nodeID, final long start) {
   if (clusterMap.containsKey(nodeID)) {
     checkQuorum();
   } else {
     vertx.setTimer(
         200,
         tid -> {
           // This can block on a monitor so it needs to run as a worker
           vertx.executeBlockingInternal(
               () -> {
                 if (System.currentTimeMillis() - start > 10000) {
                   log.warn("Timed out waiting for group information to appear");
                 } else if (!stopped) {
                   ContextImpl context = vertx.getContext();
                   try {
                     // Remove any context we have here (from the timer) otherwise will screw
                     // things up when verticles are deployed
                     ContextImpl.setContext(null);
                     checkQuorumWhenAdded(nodeID, start);
                   } finally {
                     ContextImpl.setContext(context);
                   }
                 }
                 return null;
               },
               null);
         });
   }
 }
示例#2
0
  public void stop() {
    if (!stopped) {
      if (clusterManager.isActive()) {

        clusterMap.remove(nodeID);
      }
      vertx.cancelTimer(quorumTimerID);
      stopped = true;
    }
  }
示例#3
0
 public void simulateKill() {
   if (!stopped) {
     killed = true;
     clusterManager.leave(
         ar -> {
           if (ar.failed()) {
             log.error("Failed to leave cluster", ar.cause());
           }
         });
     vertx.cancelTimer(quorumTimerID);
     stopped = true;
   }
 }
示例#4
0
 // Add the deployment to an internal list of deploymentIDs - these will be executed when a quorum
 // is attained
 private void addToHADeployList(
     final String verticleName,
     final DeploymentOptions deploymentOptions,
     final Handler<AsyncResult<String>> doneHandler) {
   toDeployOnQuorum.add(
       () -> {
         ContextImpl ctx = vertx.getContext();
         try {
           ContextImpl.setContext(null);
           deployVerticle(verticleName, deploymentOptions, doneHandler);
         } finally {
           ContextImpl.setContext(ctx);
         }
       });
 }
示例#5
0
 private void callFailoverCompleteHandler(
     FailoverCompleteHandler handler, String nodeID, JsonObject haInfo, boolean result) {
   if (handler != null) {
     CountDownLatch latch = new CountDownLatch(1);
     // The testsuite requires that this is called on a Vert.x thread
     vertx.runOnContext(
         v -> {
           handler.handle(nodeID, haInfo, result);
           latch.countDown();
         });
     try {
       latch.await(30, TimeUnit.SECONDS);
     } catch (InterruptedException ignore) {
     }
   }
 }
示例#6
0
 // Process the failover of a deployment
 private void processFailover(JsonObject failedVerticle) {
   if (failDuringFailover) {
     throw new VertxException("Oops!");
   }
   // This method must block until the failover is complete - i.e. the verticle is successfully
   // redeployed
   final String verticleName = failedVerticle.getString("verticle_name");
   final CountDownLatch latch = new CountDownLatch(1);
   final AtomicReference<Throwable> err = new AtomicReference<>();
   // Now deploy this verticle on this node
   ContextImpl ctx = vertx.getContext();
   if (ctx != null) {
     // We could be on main thread in which case we don't want to overwrite tccl
     ContextImpl.setContext(null);
   }
   JsonObject options = failedVerticle.getJsonObject("options");
   try {
     doDeployVerticle(
         verticleName,
         new DeploymentOptions(options),
         result -> {
           if (result.succeeded()) {
             log.info("Successfully redeployed verticle " + verticleName + " after failover");
           } else {
             log.error("Failed to redeploy verticle after failover", result.cause());
             err.set(result.cause());
           }
           latch.countDown();
           Throwable t = err.get();
           if (t != null) {
             throw new VertxException(t);
           }
         });
   } finally {
     if (ctx != null) {
       ContextImpl.setContext(ctx);
     }
   }
   try {
     if (!latch.await(120, TimeUnit.SECONDS)) {
       throw new VertxException("Timed out waiting for redeploy on failover");
     }
   } catch (InterruptedException e) {
     throw new IllegalStateException(e);
   }
 }
示例#7
0
 // Undeploy any HA deploymentIDs now there is no quorum
 private void undeployHADeployments() {
   for (String deploymentID : deploymentManager.deployments()) {
     Deployment dep = deploymentManager.getDeployment(deploymentID);
     if (dep != null) {
       if (dep.deploymentOptions().isHa()) {
         ContextImpl ctx = vertx.getContext();
         try {
           ContextImpl.setContext(null);
           deploymentManager.undeployVerticle(
               deploymentID,
               result -> {
                 if (result.succeeded()) {
                   log.info(
                       "Successfully undeployed HA deployment "
                           + deploymentID
                           + "-"
                           + dep.verticleIdentifier()
                           + " as there is no quorum");
                   addToHADeployList(
                       dep.verticleIdentifier(),
                       dep.deploymentOptions(),
                       result1 -> {
                         if (result1.succeeded()) {
                           log.info(
                               "Successfully redeployed verticle "
                                   + dep.verticleIdentifier()
                                   + " after quorum was re-attained");
                         } else {
                           log.error(
                               "Failed to redeploy verticle "
                                   + dep.verticleIdentifier()
                                   + " after quorum was re-attained",
                               result1.cause());
                         }
                       });
                 } else {
                   log.error("Failed to undeploy deployment on lost quorum", result.cause());
                 }
               });
         } finally {
           ContextImpl.setContext(ctx);
         }
       }
     }
   }
 }
示例#8
0
  public HAManager(
      VertxInternal vertx,
      DeploymentManager deploymentManager,
      ClusterManager clusterManager,
      int quorumSize,
      String group,
      boolean enabled) {
    this.vertx = vertx;
    this.deploymentManager = deploymentManager;
    this.clusterManager = clusterManager;
    this.quorumSize = enabled ? quorumSize : 0;
    this.group = enabled ? group : "__DISABLED__";
    this.enabled = enabled;
    this.haInfo = new JsonObject();
    haInfo.put("verticles", new JsonArray());
    haInfo.put("group", this.group);
    this.clusterMap = clusterManager.getSyncMap(CLUSTER_MAP_NAME);
    this.nodeID = clusterManager.getNodeID();
    clusterManager.nodeListener(
        new NodeListener() {
          @Override
          public void nodeAdded(String nodeID) {
            HAManager.this.nodeAdded(nodeID);
          }

          @Override
          public void nodeLeft(String leftNodeID) {
            HAManager.this.nodeLeft(leftNodeID);
          }
        });
    clusterMap.put(nodeID, haInfo.encode());
    quorumTimerID = vertx.setPeriodic(QUORUM_CHECK_PERIOD, tid -> checkHADeployments());
    // Call check quorum to compute whether we have an initial quorum
    synchronized (this) {
      checkQuorum();
    }
  }