@Override
 public HighAvailabilityMemberState masterIsAvailable(
     HighAvailabilityMemberContext context, InstanceId masterId, URI masterHaURI) {
   if (masterId.equals(context.getMyId())) {
     throw new RuntimeException(
         "i ("
             + context.getMyId()
             + ") am trying to become a slave but "
             + "someone said i am available as master");
   }
   if (masterId.equals(context.getElectedMasterId())) {
     // A member joined and we all got the same event
     return this;
   }
   throw new RuntimeException(
       "my ("
           + context.getMyId()
           + ") current master is "
           + context.getAvailableHaMaster()
           + " (elected as "
           + context.getElectedMasterId()
           + " but i got a "
           + "masterIsAvailable event for "
           + masterHaURI);
 }
 @Override
 public HighAvailabilityMemberState masterIsElected(
     HighAvailabilityMemberContext context, InstanceId masterId) {
   if (masterId.equals(context.getMyId())) {
     return TO_MASTER;
   }
   if (masterId.equals(context.getElectedMasterId())) {
     return this;
   }
   return PENDING;
 }
 @Override
 public HighAvailabilityMemberState masterIsElected(
     HighAvailabilityMemberContext context, InstanceId masterId) {
   if (masterId.equals(context.getElectedMasterId())) {
     // A member joined and we all got the same event
     return this;
   }
   if (masterId.equals(context.getMyId())) {
     return TO_MASTER;
   }
   // This may mean the master changed from the time we transitioned here
   return PENDING;
 }
 @Override
 public HighAvailabilityMemberState masterIsAvailable(
     HighAvailabilityMemberContext context, InstanceId masterId, URI masterHaURI) {
   if (masterId.equals(context.getMyId())) {
     throw new RuntimeException("Cannot transition to MASTER directly from SLAVE state");
   } else if (masterId.equals(context.getElectedMasterId())) {
     // this is just someone else that joined the cluster
     return this;
   }
   throw new RuntimeException(
       "Received a MasterIsAvailable event for "
           + masterId
           + " which is different from the current master ("
           + context.getElectedMasterId()
           + ") while in the SLAVE state (probably missed a MasterIsElected event)");
 }
  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    MemberIsAvailable that = (MemberIsAvailable) o;

    if (!clusterUri.equals(that.clusterUri)) {
      return false;
    }
    if (!instanceId.equals(that.instanceId)) {
      return false;
    }
    if (!role.equals(that.role)) {
      return false;
    }
    if (!roleUri.equals(that.roleUri)) {
      return false;
    }

    return true;
  }
 @Override
 public HighAvailabilityMemberState slaveIsAvailable(
     HighAvailabilityMemberContext context, InstanceId slaveId, URI slaveUri) {
   if (slaveId.equals(context.getMyId())) {
     throw new RuntimeException("Cannot go from pending to slave");
   }
   return this;
 }
 @Override
 public HighAvailabilityMemberState slaveIsAvailable(
     HighAvailabilityMemberContext context, InstanceId slaveId, URI slaveUri) {
   if (slaveId.equals(context.getMyId())) {
     return SLAVE;
   }
   return this;
 }
 @Override
 public int hashCode() {
   int result = role.hashCode();
   result = 31 * result + instanceId.hashCode();
   result = 31 * result + clusterUri.hashCode();
   result = 31 * result + roleUri.hashCode();
   return result;
 }
 @Override
 public HighAvailabilityMemberState slaveIsAvailable(
     HighAvailabilityMemberContext context, InstanceId slaveId, URI slaveUri) {
   if (slaveId.equals(context.getMyId())) {
     throw new RuntimeException("Cannot be master and transition to slave at the same time");
   }
   return this;
 }
 @Override
 public HighAvailabilityMemberState masterIsElected(
     HighAvailabilityMemberContext context, InstanceId masterId) {
   assert context.getAvailableHaMaster() == null;
   if (masterId.equals(context.getMyId()) && !context.isSlaveOnly()) {
     return TO_MASTER;
   }
   return PENDING;
 }
 @Override
 public HighAvailabilityMemberState masterIsElected(
     HighAvailabilityMemberContext context, InstanceId masterId) {
   assert context.getAvailableHaMaster() == null;
   if (masterId.equals(context.getMyId())) {
     return this;
   }
   return PENDING; // everything still goes
 }
 @Override
 public HighAvailabilityMemberState masterIsAvailable(
     HighAvailabilityMemberContext context, InstanceId masterId, URI masterHaURI) {
   //                    assert context.getAvailableMaster() == null;
   if (masterId.equals(context.getMyId())) {
     throw new RuntimeException(
         "Received a MasterIsAvailable event for my InstanceId while in" + " PENDING state");
   }
   return TO_SLAVE;
 }
 @Override
 public HighAvailabilityMemberState masterIsElected(
     HighAvailabilityMemberContext context, InstanceId masterId) {
   if (masterId.equals(context.getMyId())) {
     return this;
   }
   // This means we (probably) were disconnected and got back in the cluster
   // and we find out that we are not the master anymore.
   return PENDING;
 }
 @Override
 public HighAvailabilityMemberState masterIsAvailable(
     HighAvailabilityMemberContext context, InstanceId masterId, URI masterHaURI) {
   if (masterId.equals(context.getMyId())) {
     return MASTER;
   }
   throw new RuntimeException(
       "Received a MasterIsAvailable event for instance "
           + masterId
           + " while in TO_MASTER state");
 }
 @Override
 public HighAvailabilityMemberState masterIsAvailable(
     HighAvailabilityMemberContext context, InstanceId masterId, URI masterHaURI) {
   if (masterId.equals(context.getMyId())) {
     return this;
   }
   throw new RuntimeException(
       "I, "
           + context.getMyId()
           + " got a masterIsAvailable for "
           + masterHaURI
           + " (id is "
           + masterId
           + " ) while in MASTER state. Probably missed a "
           + "MasterIsElected event.");
 }
Esempio n. 16
0
  private ClusterClient newClusterClient(InstanceId id) {
    Map<String, String> configMap =
        MapUtil.stringMap(
            ClusterSettings.initial_hosts.name(), cluster.getInitialHostsConfigString(),
            ClusterSettings.server_id.name(), String.valueOf(id.toIntegerIndex()),
            ClusterSettings.cluster_server.name(), "0.0.0.0:8888");

    Config config =
        new Config(
            configMap,
            InternalAbstractGraphDatabase.Configuration.class,
            GraphDatabaseSettings.class);

    return new ClusterClient(
        new Monitors(),
        ClusterClient.adapt(config),
        new DevNullLoggingService(),
        new NotElectableElectionCredentialsProvider(),
        new ObjectStreamFactory(),
        new ObjectStreamFactory());
  }
Esempio n. 17
0
    @Override
    public HeartbeatState handle(
        HeartbeatContext context, Message<HeartbeatMessage> message, MessageHolder outgoing)
        throws Throwable {
      switch (message.getMessageType()) {
        case i_am_alive:
          {
            HeartbeatMessage.IAmAliveState state = message.getPayload();

            if (context.getClusterContext().isMe(state.getServer())) {
              break;
            }

            context.getClusterContext().getLogger(HeartbeatState.class).debug("Received " + state);

            if (state.getServer() == null) {
              break;
            }

            if (context.alive(state.getServer())) {
              // Send suspicions messages to all non-failed servers
              for (InstanceId aliveServer : context.getAlive()) {
                if (!aliveServer.equals(context.getClusterContext().getMyId())) {
                  URI aliveServerUri =
                      context.getClusterContext().configuration.getUriForId(aliveServer);
                  outgoing.offer(
                      Message.to(
                          HeartbeatMessage.suspicions,
                          aliveServerUri,
                          new HeartbeatMessage.SuspicionsState(
                              context.getSuspicionsFor(context.getClusterContext().getMyId()))));
                }
              }
            }

            context
                .getClusterContext()
                .timeouts
                .cancelTimeout(HeartbeatMessage.i_am_alive + "-" + state.getServer());
            context
                .getClusterContext()
                .timeouts
                .setTimeout(
                    HeartbeatMessage.i_am_alive + "-" + state.getServer(),
                    timeout(HeartbeatMessage.timed_out, message, state.getServer()));

            // Check if this server knows something that we don't
            if (message.hasHeader("last-learned")) {
              long lastLearned = Long.parseLong(message.getHeader("last-learned"));
              if (lastLearned
                  > context.getLearnerContext().getLastKnownLearnedInstanceInCluster()) {
                outgoing.offer(internal(LearnerMessage.catchUp, lastLearned));
              }
            }

            break;
          }

        case timed_out:
          {
            InstanceId server = message.getPayload();
            context
                .getClusterContext()
                .getLogger(HeartbeatState.class)
                .debug("Received timed out for server " + server);
            // Check if this node is no longer a part of the cluster
            if (context.getClusterContext().getConfiguration().getMembers().containsKey(server)) {
              context.suspect(server);

              context
                  .getClusterContext()
                  .timeouts
                  .setTimeout(
                      HeartbeatMessage.i_am_alive + "-" + server,
                      timeout(HeartbeatMessage.timed_out, message, server));

              // Send suspicions messages to all non-failed servers
              for (InstanceId aliveServer : context.getAlive()) {
                if (!aliveServer.equals(context.getClusterContext().getMyId())) {
                  URI sendTo =
                      context.getClusterContext().getConfiguration().getUriForId(aliveServer);
                  outgoing.offer(
                      Message.to(
                          HeartbeatMessage.suspicions,
                          sendTo,
                          new HeartbeatMessage.SuspicionsState(
                              context.getSuspicionsFor(context.getClusterContext().getMyId()))));
                }
              }
            } else {
              // If no longer part of cluster, then don't bother
              context.serverLeftCluster(server);
            }
            break;
          }

        case sendHeartbeat:
          {
            InstanceId to = message.getPayload();

            // Check if this node is no longer a part of the cluster
            if (!context.getClusterContext().isMe(to)
                && context.getClusterContext().getConfiguration().getMembers().containsKey(to)) {
              URI toSendTo = context.getClusterContext().getConfiguration().getUriForId(to);
              // Send heartbeat message to given server
              outgoing.offer(
                  to(
                          HeartbeatMessage.i_am_alive,
                          toSendTo,
                          new HeartbeatMessage.IAmAliveState(context.getClusterContext().getMyId()))
                      .setHeader(
                          "last-learned",
                          context.getLearnerContext().getLastLearnedInstanceId() + ""));

              // Set new timeout to send heartbeat to this host
              context
                  .getClusterContext()
                  .timeouts
                  .setTimeout(
                      HeartbeatMessage.sendHeartbeat + "-" + to,
                      timeout(HeartbeatMessage.sendHeartbeat, message, to));
            }
            break;
          }

        case reset_send_heartbeat:
          {
            InstanceId to = message.getPayload();

            if (!context.getClusterContext().isMe(to)) {
              String timeoutName = HeartbeatMessage.sendHeartbeat + "-" + to;
              context.getClusterContext().timeouts.cancelTimeout(timeoutName);
              context
                  .getClusterContext()
                  .timeouts
                  .setTimeout(timeoutName, timeout(HeartbeatMessage.sendHeartbeat, message, to));
            }
            break;
          }

        case suspicions:
          {
            HeartbeatMessage.SuspicionsState suspicions = message.getPayload();
            context
                .getClusterContext()
                .getLogger(HeartbeatState.class)
                .debug("Received suspicions as " + suspicions);

            URI from = new URI(message.getHeader(Message.FROM));
            InstanceId fromId = context.getClusterContext().getConfiguration().getServerId(from);
            /*
             * Remove ourselves from the suspicions received - we just received a message,
             * it's not normal to be considered failed. Whatever it was, it was transient and now it has
             * passed.
             */
            suspicions.getSuspicions().remove(context.getClusterContext().getMyId());
            context.suspicions(fromId, suspicions.getSuspicions());

            break;
          }

        case leave:
          {
            context.getClusterContext().getLogger(HeartbeatState.class).debug("Received leave");
            return start;
          }

        case addHeartbeatListener:
          {
            context.addHeartbeatListener((HeartbeatListener) message.getPayload());
            break;
          }

        case removeHeartbeatListener:
          {
            context.removeHeartbeatListener((HeartbeatListener) message.getPayload());
            break;
          }
      }

      return this;
    }
Esempio n. 18
0
    private void startMember(InstanceId serverId) throws URISyntaxException, IOException {
      Clusters.Member member = spec.getMembers().get(serverId.toIntegerIndex() - 1);
      StringBuilder initialHosts = new StringBuilder(spec.getMembers().get(0).getHost());
      for (int i = 1; i < spec.getMembers().size(); i++) {
        initialHosts.append(",").append(spec.getMembers().get(i).getHost());
      }
      File parent = new File(root, name);
      URI clusterUri = new URI("cluster://" + member.getHost());
      if (member.isFullHaMember()) {
        int clusterPort = clusterUri.getPort();
        int haPort = clusterUri.getPort() + 3000;
        File storeDir = new File(parent, "server" + serverId);
        if (storeDirInitializer != null) {
          storeDirInitializer.initializeStoreDir(serverId.toIntegerIndex(), storeDir);
        }
        GraphDatabaseBuilder builder =
            dbFactory.newHighlyAvailableDatabaseBuilder(storeDir.getAbsolutePath());
        builder.setConfig(ClusterSettings.cluster_name, name);
        builder.setConfig(ClusterSettings.initial_hosts, initialHosts.toString());
        builder.setConfig(ClusterSettings.server_id, serverId + "");
        builder.setConfig(ClusterSettings.cluster_server, "0.0.0.0:" + clusterPort);
        builder.setConfig(HaSettings.ha_server, ":" + haPort);
        builder.setConfig(OnlineBackupSettings.online_backup_enabled, Settings.FALSE);
        builder.setConfig(commonConfig);
        if (instanceConfig.containsKey(serverId.toIntegerIndex())) {
          builder.setConfig(instanceConfig.get(serverId.toIntegerIndex()));
        }

        config(builder, name, serverId);

        final HighlyAvailableGraphDatabaseProxy graphDatabase =
            new HighlyAvailableGraphDatabaseProxy(builder);

        members.put(serverId, graphDatabase);

        life.add(
            new LifecycleAdapter() {
              @Override
              public void stop() throws Throwable {
                graphDatabase.get().shutdown();
              }
            });
      } else {
        Map<String, String> config =
            MapUtil.stringMap(
                ClusterSettings.cluster_name.name(),
                name,
                ClusterSettings.initial_hosts.name(),
                initialHosts.toString(),
                ClusterSettings.server_id.name(),
                serverId + "",
                ClusterSettings.cluster_server.name(),
                "0.0.0.0:" + clusterUri.getPort(),
                GraphDatabaseSettings.store_dir.name(),
                new File(parent, "arbiter" + serverId).getAbsolutePath());
        Config config1 =
            new Config(
                config,
                InternalAbstractGraphDatabase.Configuration.class,
                GraphDatabaseSettings.class);

        ObjectStreamFactory objectStreamFactory = new ObjectStreamFactory();
        ClusterClient clusterClient =
            new ClusterClient(
                new Monitors(),
                ClusterClient.adapt(config1),
                NullLogService.getInstance(),
                new NotElectableElectionCredentialsProvider(),
                objectStreamFactory,
                objectStreamFactory);

        arbiters.add(
            new ClusterMembers(
                clusterClient,
                clusterClient,
                new ClusterMemberEvents() {
                  @Override
                  public void addClusterMemberListener(ClusterMemberListener listener) {
                    // noop
                  }

                  @Override
                  public void removeClusterMemberListener(ClusterMemberListener listener) {
                    // noop
                  }
                },
                clusterClient.getServerId()));

        life.add(new FutureLifecycleAdapter<>(clusterClient));
      }
    }
Esempio n. 19
0
 @Override
 public String toString() {
   return String.format(
       "MemberIsAvailable[ Role: %s, InstanceId: %s, Role URI: %s, Cluster URI: %s]",
       role, instanceId.toString(), roleUri.toString(), clusterUri.toString());
 }