예제 #1
0
파일: GMS.java 프로젝트: jtoerber/JGroups
    public void run() {
      long end_time, wait_time;
      List<Request> requests = new LinkedList<Request>();
      while (Thread.currentThread().equals(thread) && !suspended) {
        try {
          boolean keepGoing = false;
          end_time = System.currentTimeMillis() + max_bundling_time;
          do {
            Request firstRequest =
                (Request)
                    queue.remove(INTERVAL); // throws a TimeoutException if it runs into timeout
            requests.add(firstRequest);
            if (!view_bundling) break;
            if (queue.size() > 0) {
              Request nextReq = (Request) queue.peek();
              keepGoing = view_bundling && firstRequest.canBeProcessedTogether(nextReq);
            } else {
              wait_time = end_time - System.currentTimeMillis();
              if (wait_time > 0)
                queue.waitUntilClosed(
                    wait_time); // misnomer: waits until element has been added or q closed
              keepGoing =
                  queue.size() > 0 && firstRequest.canBeProcessedTogether((Request) queue.peek());
            }
          } while (keepGoing && System.currentTimeMillis() < end_time);

          try {
            process(requests);
          } finally {
            requests.clear();
          }
        } catch (QueueClosedException e) {
          break;
        } catch (TimeoutException e) {
          break;
        } catch (Throwable catchall) {
          Util.sleep(50);
        }
      }
    }
예제 #2
0
    /**
     * Assembles all the fragments into one buffer. Takes all Messages, and combines their buffers
     * into one buffer. This method does not check if the fragmentation is complete (use {@link
     * #isComplete()} to verify before calling this method)
     *
     * @return the complete message in one buffer
     */
    private Message assembleMessage() {
      Message retval;
      byte[] combined_buffer, tmp;
      int combined_length = 0, length, offset;
      int index = 0;

      for (Message fragment : fragments) combined_length += fragment.getLength();

      combined_buffer = new byte[combined_length];
      retval = fragments[0].copy(false); // doesn't copy the payload, but copies the headers

      for (int i = 0; i < fragments.length; i++) {
        Message fragment = fragments[i];
        fragments[i] = null; // help garbage collection a bit
        tmp = fragment.getRawBuffer();
        length = fragment.getLength();
        offset = fragment.getOffset();
        System.arraycopy(tmp, offset, combined_buffer, index, length);
        index += length;
      }

      retval.setBuffer(combined_buffer);
      return retval;
    }
예제 #3
0
파일: GMS.java 프로젝트: jtoerber/JGroups
  /**
   * Sets the new view and sends a VIEW_CHANGE event up and down the stack. If the view is a
   * MergeView (subclass of View), then digest will be non-null and has to be set before installing
   * the view.
   */
  public void installView(View new_view, Digest digest) {
    ViewId vid = new_view.getVid();
    List<Address> mbrs = new_view.getMembers();
    ltime =
        Math.max(
            vid.getId(),
            ltime); // compute the logical time, regardless of whether the view is accepted

    // Discards view with id lower than or equal to our own. Will be installed without check if it
    // is the first view
    if (view != null) {
      ViewId view_id = view.getViewId();
      int rc = vid.compareToIDs(view_id);
      if (rc <= 0) {
        if (log.isWarnEnabled()
            && rc < 0
            && log_view_warnings) { // only scream if view is smaller, silently discard same views
          log.warn(
              local_addr
                  + ": received view < current view;"
                  + " discarding it (current vid: "
                  + view_id
                  + ", new vid: "
                  + vid
                  + ')');
        }
        return;
      }
    }

    /* Check for self-inclusion: if I'm not part of the new membership, I just discard it.
    This ensures that messages sent in view V1 are only received by members of V1 */
    if (!mbrs.contains(local_addr)) {
      if (log.isWarnEnabled() && log_view_warnings)
        log.warn(local_addr + ": not member of view " + new_view.getViewId() + "; discarding it");
      return;
    }

    if (digest != null) {
      if (new_view instanceof MergeView) mergeDigest(digest);
      else setDigest(digest);
    }

    if (log.isDebugEnabled()) log.debug(local_addr + ": installing view " + new_view);

    Event view_event;
    synchronized (members) {
      view = new View(new_view.getVid(), new_view.getMembers());
      view_event = new Event(Event.VIEW_CHANGE, new_view);

      // Set the membership. Take into account joining members
      if (!mbrs.isEmpty()) {
        members.set(mbrs);
        tmp_members.set(members);
        joining.removeAll(mbrs); // remove all members in mbrs from joining
        // remove all elements from 'leaving' that are not in 'mbrs'
        leaving.retainAll(mbrs);

        tmp_members.add(joining); // add members that haven't yet shown up in the membership
        tmp_members.remove(
            leaving); // remove members that haven't yet been removed from the membership

        // add to prev_members
        for (Address addr : mbrs) {
          if (!prev_members.contains(addr)) prev_members.add(addr);
        }
      }

      Address coord = determineCoordinator();
      if (coord != null && coord.equals(local_addr) && !haveCoordinatorRole()) {
        becomeCoordinator();
      } else {
        if (haveCoordinatorRole() && !local_addr.equals(coord)) {
          becomeParticipant();
          merge_ack_collector.reset(null); // we don't need this one anymore
        }
      }
    }

    // - Changed order of passing view up and down (http://jira.jboss.com/jira/browse/JGRP-347)
    // - Changed it back (bela Sept 4 2007): http://jira.jboss.com/jira/browse/JGRP-564
    // - Moved sending up view_event out of the synchronized block (bela Nov 2011)
    down_prot.down(view_event); // needed e.g. by failure detector or UDP
    up_prot.up(view_event);

    List<Address> tmp_mbrs = new_view.getMembers();
    ack_collector.retainAll(tmp_mbrs);
    merge_ack_collector.retainAll(tmp_mbrs);

    if (new_view instanceof MergeView) merger.forceCancelMerge();

    if (stats) {
      num_views++;
      prev_views.add(new Tuple<View, Long>(new_view, System.currentTimeMillis()));
    }
  }