Beispiel #1
0
  public TrPeerInfo getPeerForAssimilation() {
    if (peers.isEmpty()) {
      // We need to use a public peer
      final ArrayList<File> publicNodeIdFiles = node.getPublicNodeIdFiles();
      final File pubPeerFile =
          publicNodeIdFiles.get(TrUtils.rand.nextInt(publicNodeIdFiles.size()));
      final TrPeerInfo pnii = Persistence.loadReadOnly(TrPeerInfo.class, pubPeerFile);
      return pnii;
    } else {
      /**
       * Here we use a trick to pick peers in proportion to the probability that they will be the
       * fastest peer
       */
      TrPeerInfo bestPeer = null;
      double bestTimeEstimate = Double.MAX_VALUE;
      final LinearStat globalSuccessTime = new LinearStat(Integer.MAX_VALUE);
      globalSuccessTime.sample(1000);
      globalSuccessTime.sample(2000);
      for (final TrPeerInfo ifo : peers.values()) {
        if (ifo.assimilation.successTimeSqrt.total > 0) {
          globalSuccessTime.sample(ifo.assimilation.successTimeSqrt.mean());
        }
      }
      for (final Entry<PhysicalNetworkLocation, TrPeerInfo> e : peers.entrySet()) {
        final double guessFailureProb = e.getValue().assimilation.successRate.getBetaRandom();
        double guessSuccessTime;
        // If we don't have at least 2 samples, use our global success
        // time
        if (e.getValue().assimilation.successTimeSqrt.total > 2) {
          final double guessSuccessTimeSqrt =
              e.getValue().assimilation.successTimeSqrt.getNormalRandom();
          guessSuccessTime = guessSuccessTimeSqrt * guessSuccessTimeSqrt;
        } else {
          final double guessSuccessTimeSqrt = globalSuccessTime.getNormalRandom();
          guessSuccessTime = guessSuccessTimeSqrt * guessSuccessTimeSqrt;
        }
        double timeEstimate =
            guessSuccessTime
                + AssimilateSessionImpl.RELAY_ASSIMILATION_TIMEOUT_SECONDS
                    * 1000l
                    * guessFailureProb;

        if (lastAttemptedRelays.contains(e.getValue())) {
          timeEstimate *= RECENTLY_ATTEMPTED_PENALTY;
        }

        if (timeEstimate < bestTimeEstimate) {
          bestPeer = e.getValue();
          bestTimeEstimate = timeEstimate;
        }
      }
      lastAttemptedRelays.add(bestPeer);
      while (lastAttemptedRelays.size() > 5) {
        lastAttemptedRelays.poll();
      }
      return bestPeer;
    }
  }
Beispiel #2
0
  /**
   * If you need to modify a peer's information you must do it using this method, as it ensures that
   * persistent peer information gets persisted
   *
   * @param addr
   * @param updateFunction
   */
  public void updatePeerInfo(
      final PhysicalNetworkLocation addr, final Function<TrPeerInfo, Void> updateFunction) {
    final File pubNodeFile = node.getFileForPublicNode(addr);
    if (pubNodeFile.exists()) {
      Persistence.loadAndModify(
          TrPeerInfo.class,
          pubNodeFile,
          new Persistence.ModifyBlock<TrPeerInfo>() {

            public void run(final TrPeerInfo object, final Modified modified) {
              updateFunction.apply(object);
            }
          });
    } else {
      updateFunction.apply(peers.get(addr));
    }
  }