Example #1
0
  /**
   * Invoked upon receiving a MERGE event from the MERGE layer. Starts the merge protocol. See
   * description of protocol in DESIGN.
   *
   * @param views A List of <em>different</em> views detected by the merge protocol
   */
  public void merge(Map<Address, View> views) {
    if (isMergeInProgress()) {
      if (log.isTraceEnabled())
        log.trace(gms.local_addr + ": merge is already running (merge_id=" + merge_id + ")");
      return;
    }

    // we need the merge *coordinators* not merge participants because not everyone can lead a merge
    // !
    Collection<Address> coords = Util.determineMergeCoords(views);
    Collection<Address> merge_participants = Util.determineMergeParticipants(views);
    Membership tmp =
        new Membership(coords); // establish a deterministic order, so that coords can elect leader
    tmp.sort();
    Address merge_leader = tmp.elementAt(0);
    if (log.isDebugEnabled()) log.debug("determining merge leader from " + merge_participants);
    if (merge_leader.equals(gms.local_addr)) {
      if (log.isDebugEnabled())
        log.debug(
            "I ("
                + gms.local_addr
                + ") will be the leader. Starting the merge task for "
                + merge_participants);
      merge_task.start(views);
    } else {
      if (log.isDebugEnabled())
        log.debug(
            "I ("
                + gms.local_addr
                + ") am not the merge leader, "
                + "waiting for merge leader ("
                + merge_leader
                + ") to initiate merge");
    }
  }
Example #2
0
 /** Checks whether the potential_new_coord would be the new coordinator (2nd in line) */
 protected boolean wouldBeNewCoordinator(Address potential_new_coord) {
   if (potential_new_coord == null) return false;
   synchronized (members) {
     if (members.size() < 2) return false;
     Address new_coord = members.elementAt(1); // member at 2nd place
     return new_coord != null && new_coord.equals(potential_new_coord);
   }
 }
Example #3
0
    /**
     * Merge all MergeData. All MergeData elements should be disjunct (both views and digests).
     * However, this method is prepared to resolve duplicate entries (for the same member).
     * Resolution strategy for views is to merge only 1 of the duplicate members. Resolution
     * strategy for digests is to take the higher seqnos for duplicate digests.
     *
     * <p>After merging all members into a Membership and subsequent sorting, the first member of
     * the sorted membership will be the new coordinator. This method has a lock on merge_rsps.
     *
     * @param merge_rsps A list of MergeData items. Elements with merge_rejected=true were removed
     *     before. Is guaranteed not to be null and to contain at least 1 member.
     */
    private MergeData consolidateMergeData(Vector<MergeData> merge_rsps) {
      long logical_time = 0; // for new_vid
      Membership new_mbrs = new Membership();
      Vector<View> subgroups =
          new Vector<View>(11); // contains a list of Views, each View is a subgroup

      for (MergeData tmp_data : merge_rsps) {
        View tmp_view = tmp_data.getView();
        if (tmp_view != null) {
          ViewId tmp_vid = tmp_view.getVid();
          if (tmp_vid != null) {
            // compute the new view id (max of all vids +1)
            logical_time = Math.max(logical_time, tmp_vid.getId());
          }
          // merge all membership lists into one (prevent duplicates)
          new_mbrs.add(tmp_view.getMembers());
          subgroups.addElement((View) tmp_view.clone());
        }
      }

      // the new coordinator is the first member of the consolidated & sorted membership list
      new_mbrs.sort();
      Address new_coord = new_mbrs.size() > 0 ? new_mbrs.elementAt(0) : null;
      if (new_coord == null) {
        if (log.isErrorEnabled()) log.error("new_coord == null");
        return null;
      }
      // should be the highest view ID seen up to now plus 1
      ViewId new_vid = new ViewId(new_coord, logical_time + 1);

      // determine the new view
      MergeView new_view = new MergeView(new_vid, new_mbrs.getMembers(), subgroups);

      // determine the new digest
      Digest new_digest = consolidateDigests(merge_rsps, new_mbrs.size());
      if (new_digest == null) {
        if (log.isErrorEnabled())
          log.error("Merge leader " + gms.local_addr + ": could not consolidate digest for merge");
        return null;
      }
      if (log.isDebugEnabled())
        log.debug(
            "Merge leader "
                + gms.local_addr
                + ": consolidated view="
                + new_view
                + "\nconsolidated digest="
                + new_digest);
      return new MergeData(gms.local_addr, new_view, new_digest);
    }
Example #4
0
 protected Address determineCoordinator() {
   synchronized (members) {
     return members.size() > 0 ? members.elementAt(0) : null;
   }
 }