Esempio n. 1
0
    public int compare(Object a, Object b) {
      RemoteFileDesc pongA = (RemoteFileDesc) a;
      RemoteFileDesc pongB = (RemoteFileDesc) b;

      // Multicasts are best
      if (pongA.isReplyToMulticast() != pongB.isReplyToMulticast()) {
        if (pongA.isReplyToMulticast()) return -1;
        else return 1;
      }

      // HeadPongs with highest number of free slots get the highest priority
      if (pongA.getQueueStatus() > pongB.getQueueStatus()) return 1;
      else if (pongA.getQueueStatus() < pongB.getQueueStatus()) return -1;

      // Within the same queue rank, firewalled hosts get priority
      if (pongA.needsPush() != pongB.needsPush()) {
        if (pongA.needsPush()) return -1;
        else return 1;
      }

      // Within the same queue/fwall, partial hosts get priority
      if (pongA.isPartialSource() != pongB.isPartialSource()) {
        if (pongA.isPartialSource()) return -1;
        else return 1;
      }

      // the two pongs seem completely the same
      return pongA.hashCode() - pongB.hashCode();
    }
Esempio n. 2
0
  public synchronized RemoteFileDesc getBest() throws NoSuchElementException {
    if (!hasMore()) return null;
    RemoteFileDesc ret;

    // try a verified host
    if (!verifiedHosts.isEmpty()) {
      LOG.debug("getting a verified host");
      ret = (RemoteFileDesc) verifiedHosts.first();
      verifiedHosts.remove(ret);
    } else {
      LOG.debug("getting a non-verified host");
      // use the legacy ranking logic to select a non-verified host
      Iterator dual = new DualIterator(testedLocations.iterator(), newHosts.iterator());
      ret = LegacyRanker.getBest(dual);
      newHosts.remove(ret);
      testedLocations.remove(ret);
      if (ret.needsPush()) {
        for (Iterator iter = ret.getPushProxies().iterator(); iter.hasNext(); )
          pingedHosts.remove(iter.next());
      } else pingedHosts.remove(ret);
    }

    pingNewHosts();

    if (LOG.isDebugEnabled())
      LOG.debug("the best host we came up with is " + ret + " " + ret.getPushAddr());
    return ret;
  }
Esempio n. 3
0
  /** Informs the Ranker that a host has replied with a HeadPing */
  public void processMessage(Message m, ReplyHandler handler) {

    MeshHandler mesh;
    RemoteFileDesc rfd;
    Collection alts = null;
    // this -> meshHandler NOT ok
    synchronized (this) {
      if (!running) return;

      if (!(m instanceof HeadPong)) return;

      HeadPong pong = (HeadPong) m;

      if (!pingedHosts.containsKey(handler)) return;

      rfd = (RemoteFileDesc) pingedHosts.remove(handler);
      testedLocations.remove(rfd);

      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "received a pong "
                + pong
                + " from "
                + handler
                + " for rfd "
                + rfd
                + " with PE "
                + rfd.getPushAddr());
      }

      // older push proxies do not route but respond directly, we want to get responses
      // from other push proxies
      if (!pong.hasFile() && !pong.isGGEPPong() && rfd.needsPush()) return;

      // if the pong is firewalled, remove the other proxies from the
      // pinged set
      if (pong.isFirewalled()) {
        for (Iterator iter = rfd.getPushProxies().iterator(); iter.hasNext(); )
          pingedHosts.remove(iter.next());
      }

      mesh = meshHandler;
      if (pong.hasFile()) {
        // update the rfd with information from the pong
        pong.updateRFD(rfd);

        // if the remote host is busy, re-add him for later ranking
        if (rfd.isBusy()) newHosts.add(rfd);
        else verifiedHosts.add(rfd);

        alts = pong.getAllLocsRFD(rfd);
      }
    }

    // if the pong didn't have the file, drop it
    // otherwise add any altlocs the pong had to our known hosts
    if (alts == null) mesh.informMesh(rfd, false);
    else mesh.addPossibleSources(alts);
  }
Esempio n. 4
0
  /** pings a bunch of hosts if necessary */
  private void pingNewHosts() {
    // if we have reached our desired # of altlocs, don't ping
    if (isCancelled()) return;

    // if we don't have anybody to ping, don't ping
    if (!hasNonBusy()) return;

    // if we haven't found a single RFD with URN, don't ping anybody
    if (sha1 == null) return;

    // if its not time to ping yet, don't ping
    // use the same interval as workers for now
    long now = System.currentTimeMillis();
    if (now - lastPingTime < DownloadSettings.WORKER_INTERVAL.getValue()) return;

    // create a ping for the non-firewalled hosts
    HeadPing ping = new HeadPing(myGUID, sha1, getPingFlags());

    // prepare a batch of hosts to ping
    int batch = DownloadSettings.PING_BATCH.getValue();
    List toSend = new ArrayList(batch);
    int sent = 0;
    for (Iterator iter = newHosts.iterator(); iter.hasNext() && sent < batch; ) {
      RemoteFileDesc rfd = (RemoteFileDesc) iter.next();
      if (rfd.isBusy(now)) continue;
      iter.remove();

      if (rfd.needsPush()) {
        if (rfd.getPushProxies().size() > 0 && rfd.getSHA1Urn() != null) pingProxies(rfd);
      } else {
        pingedHosts.put(rfd, rfd);
        toSend.add(rfd);
      }
      testedLocations.add(rfd);
      sent++;
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "\nverified hosts "
              + verifiedHosts.size()
              + "\npingedHosts "
              + pingedHosts.values().size()
              + "\nnewHosts "
              + newHosts.size()
              + "\npinging hosts: "
              + sent);
    }

    pinger.rank(toSend, null, this, ping);
    lastPingTime = now;
  }