예제 #1
0
  /**
   * Handles a message. Knows type "collectiveUpdate-"+name only. It is the responsibility of the
   * owner to propagate messages of this type using this method.
   */
  public boolean handleMessage(Message m, Object o) {

    if (!shouldLive || !m.getType().equals("collectiveUpdate-" + name)) return false;

    final String logSender = observer + "#collectiveUpdate";

    Logger.debug(logSender, "Update from " + m.getSender());

    /**/
    if (!m.getRecipient().name.equals(contributor.getName()))
      Logger.warning(
          logSender,
          "Recipient and my contributor are not the same:\n"
              + "Recipient: "
              + m.getRecipient().name
              + "\n"
              + "Contributor: "
              + contributor.getName(),
          null);
    /**/

    Collective c = (Collective) o;

    // --- reset array representations
    cacheCollection = null;
    commandCollection = null;

    // --- remove possible garbage
    cache.remove(m.getRecipient().name);
    c.cache.remove(m.getRecipient().name);
    cache.remove(m.getSender().name);
    c.cache.remove(m.getSender().name);

    // --- sending our contributions
    if (contributor == null)
      Logger.warning(logSender, "Non-contributor observer is known by " + m.getSender(), null);
    updateLocalInfo();
    m.setReply(this);

    // --- update containers
    repairSenderAddress(c, m.getSender());
    merge(c);
    observer.collectiveUpdated((ContributionBox) cache.get(m.getSender().name));

    return true;
  }
예제 #2
0
  /**
   * Construct a Collective object.
   *
   * @param c The contributions, the commands and the name will be initialized from this object.
   * @param o The observer that reads information from the collective. It must be non-null.
   * @param cb The contributor that contributes to the collective effort.
   * @param c The controller that issues collective-wide commands.
   */
  public Collective(Collective c, Observer o, Contributor cb, Controller cr) {

    this(c.name, o, cb, cr);

    if (c == null) throw new IllegalArgumentException("null collective");

    if (c.cache != null) cache.putAll(c.cache);
    if (c.commands != null) commands.putAll(c.commands);
    if (contributor != null) cache.remove(contributor.getName());
  }
예제 #3
0
  /**
   * Updates local contribution and commands. Called before information exchange attempts. Uses
   * local address of contributor (if it is not null), this is replaced on the other side of the
   * communication channel by the correct global address.
   */
  private synchronized void updateLocalInfo() {

    if (contributor != null) {
      myContribution =
          new ContributionBox(new Address(contributor.getName()), contributor.getContribution());
    }

    final Long now = new Long(System.currentTimeMillis());
    if (controller != null) {
      Set newcomms = controller.getCommands();
      if (newcomms == null) return;
      Iterator i = newcomms.iterator();
      while (i.hasNext()) commands.put(i.next(), now);
    }
  }
예제 #4
0
  /**
   * Initiates an information exchange with a known and living other base if such a base exists.
   *
   * @return true if refresh was succesful, false otherwise.
   */
  private boolean refresh() {

    final String logSender = observer + "#refresh";
    final String contrName = ((contributor != null) ? contributor.getName() : null);

    // --- refreshing local contribution and commands
    updateLocalInfo();

    // --- creating a random permutation of peers
    Vector peers = null;
    synchronized (cache) {
      peers = new Vector(cache.values());
      // just to be sure, shouldn't be there anyway
      if (contrName != null) peers.remove(cache.get(contrName));
    }
    Collections.shuffle(peers);
    if (peers.isEmpty()) {
      Logger.debug(logSender, "no peers in cache");
      return false;
    }

    // --- reset array representations
    cacheCollection = null;
    commandCollection = null;

    // --- trying to talk to random peer
    IRequest answer = null;
    Address peer = null;
    for (int i = 0; i < peers.size(); ++i) {
      if (!shouldLive) return false;

      peer = ((ContributionBox) peers.get(i)).contributor;
      Logger.debug(logSender, "asking " + peer);

      answer = observer.fireMessage(peer, "collectiveUpdate-" + name, this);
      while (answer.getStatus() == IRequest.WAITING) {
        try {
          Thread.sleep(100);
        } catch (Exception e) {
        }
      }
      if (answer.getStatus() == IRequest.DONE) break;
      Logger.debug(logSender, "not accessable: " + peer);
    }

    if (answer.getStatus() != IRequest.DONE) {
      Logger.debug(logSender, "no accessable peers");
      observer.collectiveUpdated(null);
      return false;
    } else {
      Collective c = (Collective) answer.getInfo("reply");

      // --- remove possible garbage
      if (contributor != null) {
        cache.remove(contributor.getName());
        c.cache.remove(contributor.getName());
      }
      cache.remove(peer.name);
      c.cache.remove(peer.name);

      repairSenderAddress(c, peer);
      merge(c);
      observer.collectiveUpdated((ContributionBox) cache.get(c.myContribution.contributor.name));
      return true;
    }
  }