Beispiel #1
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.");
    }
  }
Beispiel #2
0
  /**
   * Release monitor resources and shut down the monitor.
   *
   * @throws InterruptedException
   */
  public synchronized void shutdown() throws InterruptedException {

    boolean changed = shutdown.compareAndSet(false, true);
    if (!changed) {
      return;
    }
    LoggerUtils.logMsg(logger, formatter, Level.INFO, "Shutting down monitor " + nameIdPair);
    if (learner != null) {
      learner.shutdown();
    }
    if (serviceDispatcher != null) {
      serviceDispatcher.shutdown();
    }
  }