Ejemplo n.º 1
0
  /**
   * Any member of 'membership' that is not in the new view is flagged as SUSPECTED. Any member in
   * the new view that is <em>not</em> in the membership (ie, the set of responses expected for the
   * current RPC) will <em>not</em> be added to it. If we did this we might run into the following
   * problem:
   *
   * <ul>
   *   <li>Membership is {A,B}
   *   <li>A sends a synchronous group RPC (which sleeps for 60 secs in the invocation handler)
   *   <li>C joins while A waits for responses from A and B
   *   <li>If this would generate a new view {A,B,C} and if this expanded the response set to
   *       {A,B,C}, A would wait forever on C's response because C never received the request in the
   *       first place, therefore won't send a response.
   * </ul>
   */
  public void viewChange(View new_view) {
    Vector<Address> mbrs = new_view != null ? new_view.getMembers() : null;
    if (mbrs == null) return;

    boolean changed = false;
    if (requests == null || requests.isEmpty()) return;

    lock.lock();
    try {
      for (Map.Entry<Address, Rsp> entry : requests.entrySet()) {
        Address mbr = entry.getKey();
        if (!mbrs.contains(mbr)) {
          Rsp rsp = entry.getValue();
          rsp.setValue(null);
          if (rsp.setSuspected(true)) {
            num_suspected++;
            changed = true;
          }
        }
      }
      if (changed) completed.signalAll();
    } finally {
      lock.unlock();
    }
    if (changed) checkCompletion(this);
  }
Ejemplo n.º 2
0
  /**
   * <b>Callback</b> (called by RequestCorrelator or Transport). Adds a response to the response
   * table. When all responses have been received, <code>execute()</code> returns.
   */
  public void receiveResponse(Object response_value, Address sender) {
    if (done) return;
    Rsp rsp = requests.get(sender);
    if (rsp == null) return;

    RspFilter rsp_filter = options.getRspFilter();
    boolean responseReceived = false;
    if (!rsp.wasReceived()) {
      if ((responseReceived =
          (rsp_filter == null) || rsp_filter.isAcceptable(response_value, sender)))
        rsp.setValue(response_value);
      rsp.setReceived(responseReceived);
    }

    lock.lock();
    try {
      if (responseReceived) num_received++;
      done = rsp_filter == null ? responsesComplete() : !rsp_filter.needMoreResponses();
      if (responseReceived || done) completed.signalAll(); // wakes up execute()
      if (done && corr != null) corr.done(req_id);
    } finally {
      lock.unlock();
    }
    if (responseReceived || done) checkCompletion(this);
  }
Ejemplo n.º 3
0
  /**
   * <b>Callback</b> (called by RequestCorrelator or Transport). Report to <code>GroupRequest</code>
   * that a member is reported as faulty (suspected). This method would probably be called when
   * getting a suspect message from a failure detector (where available). It is used to exclude
   * faulty members from the response list.
   */
  public void suspect(Address suspected_member) {
    if (suspected_member == null) return;

    boolean changed = false;
    Rsp rsp = requests.get(suspected_member);
    if (rsp != null) {
      if (rsp.setSuspected(true)) {
        rsp.setValue(null);
        changed = true;
        lock.lock();
        try {
          num_suspected++;
          completed.signalAll();
        } finally {
          lock.unlock();
        }
      }
    }

    if (changed) checkCompletion(this);
  }