예제 #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");
    }
  }
예제 #2
0
  public static void testDetermineMergeParticipantsAndMergeCoords4() {
    Address a = Util.createRandomAddress(),
        b = Util.createRandomAddress(),
        c = Util.createRandomAddress(),
        d = Util.createRandomAddress();
    org.jgroups.util.UUID.add(a, "A");
    org.jgroups.util.UUID.add(b, "B");
    org.jgroups.util.UUID.add(c, "C");
    org.jgroups.util.UUID.add(d, "D");

    View v1 = View.create(a, 1, a, b);
    View v2 = View.create(c, 1, c, d);

    Map<Address, View> map = new HashMap<>();
    map.put(a, v1);
    map.put(b, v1);
    map.put(d, v2);

    StringBuilder sb = new StringBuilder("map:\n");
    for (Map.Entry<Address, View> entry : map.entrySet())
      sb.append(entry.getKey() + ": " + entry.getValue() + "\n");
    System.out.println(sb);

    Collection<Address> merge_participants = Util.determineMergeParticipants(map);
    System.out.println("merge_participants = " + merge_participants);
    assert merge_participants.size() == 3;
    assert merge_participants.contains(a)
        && merge_participants.contains(c)
        && merge_participants.contains(d);

    Collection<Address> merge_coords = Util.determineMergeCoords(map);
    System.out.println("merge_coords = " + merge_coords);
    assert merge_coords.size() == 2;
    assert merge_coords.contains(a) && merge_coords.contains(c);
  }
예제 #3
0
    /**
     * @param views Guaranteed to be non-null and to have >= 2 members, or else this thread would
     *     not be started
     */
    public synchronized void start(Map<Address, View> views) {
      if (thread == null || thread.isAlive()) {
        this.coords.clear();

        // now remove all members which don't have us in their view, so RPCs won't block (e.g.
        // FLUSH)
        // https://jira.jboss.org/browse/JGRP-1061
        sanitizeViews(views);

        // Add all different coordinators of the views into the hashmap and sets their members:
        Collection<Address> coordinators = Util.determineMergeCoords(views);
        for (Address coord : coordinators) {
          View view = views.get(coord);
          if (view != null) this.coords.put(coord, new ArrayList<Address>(view.getMembers()));
        }

        // For the merge participants which are not coordinator, we simply add them, and the
        // associated
        // membership list consists only of themselves
        Collection<Address> merge_participants = Util.determineMergeParticipants(views);
        merge_participants.removeAll(coordinators);
        for (Address merge_participant : merge_participants) {
          Collection<Address> tmp = new ArrayList<Address>();
          tmp.add(merge_participant);
          coords.putIfAbsent(merge_participant, tmp);
        }

        thread = gms.getThreadFactory().newThread(this, "MergeTask");
        thread.setDaemon(true);
        thread.start();
      }
    }