Ejemplo n.º 1
0
  /**
   * Identifies the master of the replication group, resulting from the last successful election.
   * This method relies on the helper nodes supplied to the monitor and queries them for the master.
   *
   * <p>This method is useful when a Monitor first starts up and the Master needs to be determined.
   * Once a Monitor is registered and the Listener has been started, it's kept up to date via events
   * that are delivered to the Listener.
   *
   * @return the id associated with the master replication node.
   * @throws UnknownMasterException if the master could not be determined from the set of helpers
   *     made available to the Monitor.
   * @throws EnvironmentFailureException if an unexpected, internal or environment-wide failure
   *     occurs.
   * @throws IllegalStateException if the monitor has been shutdown.
   */
  public String getMasterNodeName() throws UnknownMasterException {

    if (shutdown.get()) {
      throw new IllegalStateException("The monitor has been shutdown");
    }
    return repGroupAdmin.getMasterNodeName();
  }
Ejemplo n.º 2
0
  /**
   * Registers the monitor with the group so that it can be kept informed about the outcome of
   * elections and group membership changes. The monitor, just like a replication node, is
   * identified by its nodeName. The Monitor uses the helper nodes to locate a master with which it
   * can register itself. If the helper nodes are not available the registration will fail.
   *
   * <p>A monitor must be registered at least once, if it needs to be kept up to date about ongoing
   * election results and group changes. Attempts to re-register the same monitor are ignored.
   * Registration, once it has been completed successfully persists beyond the lifetime of the
   * Monitor instance and does not need to be repeated. Repeated registrations are benign and merely
   * confirm that the current monitor configuration is consistent with earlier registrations of this
   * monitor.
   *
   * @return the node that is the current master
   * @throws EnvironmentFailureException if an unexpected, internal or environment-wide failure
   *     occurs.
   * @throws IllegalStateException if the monitor has been shutdown, or no helper sockets were
   *     specified at Monitor initialization.
   */
  public ReplicationNode register() throws EnvironmentFailureException {

    if (shutdown.get()) {
      throw new IllegalStateException("The monitor has been shutdown");
    }

    if (repGroupAdmin.getHelperSockets().size() == 0) {
      throw new IllegalStateException("No helper sockets were specified at Monitor initialization");
    }
    RepNodeImpl monitorNode =
        new RepNodeImpl(
            nameIdPair,
            NodeType.MONITOR,
            monitorConfig.getNodeHostname(),
            monitorConfig.getNodePort());
    /* Ensure that the monitor is part of the group. */
    return repGroupAdmin.ensureMonitor(monitorNode);
  }
Ejemplo n.º 3
0
  /**
   * Returns the current composition of the group. It does so by first querying the helpers to
   * determine the master and then obtaining the group information from the master.
   *
   * @return an instance of RepGroup denoting the current composition of the group
   * @throws UnknownMasterException if the master could not be determined from the set of helpers
   *     made available to the Monitor.
   * @throws EnvironmentFailureException if an unexpected, internal or environment-wide failure
   *     occurs.
   * @throws IllegalStateException if the monitor has been shutdown.
   */
  public ReplicationGroup getGroup() throws UnknownMasterException, DatabaseException {

    if (shutdown.get()) {
      throw new IllegalStateException("The monitor has been shutdown");
    }

    /*
     * TODO: Should we use this information to update the helper set as an
     * optimization?
     */
    return repGroupAdmin.getGroup();
  }
Ejemplo n.º 4
0
  /**
   * Starts the Listener so it's actively listening for election results and broadcasts of
   * replication group changes.
   *
   * <p>The Monitor must have been previously registered with the replication group via the <code>
   * register()</code> method so that other nodes in the group are aware of it and can keep it
   * current. If the monitor has not been registered, it will not be updated, that is, its listener
   * will not be invoked. The registration needs to be done exactly once.
   *
   * <p>Once the registration has been completed, the Monitor can start listening even when none of
   * the other nodes in the group are available. It will be contacted automatically by the other
   * nodes when they come up and hold a successful election.
   *
   * <p>Invoking <code>startListener</code> results in a synchronous callback to the application via
   * the {@link MonitorChangeListener#notify(NewMasterEvent)} method, if there is a current Master.
   * If there is no Master at this time then the callback takes place asynchronously, after the
   * method returns, when a Master is eventually elected.
   *
   * @param newListener the listener used to monitor events of interest.
   * @throws EnvironmentFailureException if an unexpected, internal or environment-wide failure
   *     occurs.
   * @throws IOException if the monitor socket could not be set up
   * @throws IllegalArgumentException if an invalid parameter is specified.
   * @throws IllegalStateException if the monitor has been shutdown, or a listener has already been
   *     established.
   */
  public void startListener(MonitorChangeListener newListener)
      throws DatabaseException, IOException {

    if (shutdown.get()) {
      throw new IllegalStateException("The monitor has been shutdown");
    }
    if (newListener == null) {
      throw new IllegalArgumentException(
          "A MonitorChangeListener must be associated with "
              + " this Monitor when invoking this method");
    }
    if (this.monitorChangeListener != null) {
      throw new IllegalStateException("A Listener has already been established");
    }

    this.monitorChangeListener = newListener;

    serviceDispatcher = new ServiceDispatcher(monitorConfig.getNodeSocketAddress());
    serviceDispatcher.start();
    Protocol electionProtocol =
        new Protocol(
            TimebasedProposalGenerator.getParser(),
            MasterValue.getParser(),
            monitorConfig.getGroupName(),
            nameIdPair,
            null);
    learner = new Learner(electionProtocol, serviceDispatcher, nameIdPair);
    serviceDispatcher.register(new MonitorService(this, serviceDispatcher));
    masterChangeListener = new MasterChangeListener();
    learner.addListener(masterChangeListener);
    learner.start();
    try {
      /* Notify the listener about the current master. */
      final ReplicationGroup repGroup = repGroupAdmin.getGroup();
      final RepGroupImpl group = RepInternal.getRepGroupImpl(repGroup);

      /*
       * In the absence of a network failure, the query should result in
       * a call to the notify method of MonitorChanegListener.
       */
      learner.queryForMaster(group.getLearnerSockets());

      /* Notify JoinGroupEvents for those current active nodes. */
      notifyJoinGroupEventsForActiveNodes(repGroup);
    } catch (UnknownMasterException ume) {
      /* The Listener will be informed when a Master is elected. */
      LoggerUtils.logMsg(logger, formatter, Level.INFO, "No current master.");
    }
  }