@Override
  public void memberDeparted(DistributionManager distributionManager,
      final InternalDistributedMember id, final boolean crashed) {
    FunctionInvocationTargetException fite;
    if (id != null) {
      synchronized (members) {
        if (removeMember(id, true)) {
          if (!fn.isHA()) {
            fite = new FunctionInvocationTargetException(
                String.format("memberDeparted event for < %s > crashed, %s",
                    id, crashed),
                id);
          } else {
            fite = new InternalFunctionInvocationTargetException(
                String.format("memberDeparted event for < %s > crashed, %s",
                    id, crashed),
                id);
            execution.addFailedNode(id.getId());
          }
          fites.add(fite);
        }
        checkIfDone();
      }
    } else {
      Exception e = new Exception(
          "memberDeparted got null memberId");
      logger.info(String.format("memberDeparted got null memberId crashed=%s",
          crashed),
          e);
    }
  }
Contract of {@link ReplyProcessor21#stillWaiting()} is that it never returns true after
returning false.
geode-core/src/main/java/org/apache/geode/internal/cache/partitioned/PRFunctionStreamingResultCollector.java