Ejemplo n.º 1
0
  void handleGossip(Connection connection) throws IOException {
    ARRGCacheEntry peerEntry = new ARRGCacheEntry(connection.in());

    int receiveCount = connection.in().readInt();

    ARRGCacheEntry[] receivedEntries = new ARRGCacheEntry[receiveCount];

    for (int i = 0; i < receiveCount; i++) {
      receivedEntries[i] = new ARRGCacheEntry(connection.in());
    }

    connection.sendOKReply();

    self.writeTo(connection.out());

    ARRGCacheEntry[] sendEntries = cache.getRandomEntries(GOSSIP_SIZE, true);
    connection.out().writeInt(sendEntries.length);
    for (ARRGCacheEntry entry : sendEntries) {
      entry.writeTo(connection.out());
    }

    connection.out().flush();

    connection.close();

    cache.add(peerEntry);
    cache.add(receivedEntries);

    resetLastGossip();

    logger.debug("bootstrap service for " + poolName + " received request from " + peerEntry);
  }
Ejemplo n.º 2
0
  VirtualSocketAddress getRandomMember() {
    ARRGCacheEntry result = cache.getRandomEntry(false);

    if (result == null) {
      return null;
    }

    return result.getAddress();
  }
Ejemplo n.º 3
0
  public void run() {
    while (!ended()) {
      ARRGCacheEntry victim = cache.getRandomEntry(true);

      boolean success = false;

      // first try normal cache
      if (victim != null) {
        try {
          gossip(victim.getAddress(), CONNECT_TIMEOUT, false);
          fallbackCache.add(victim);
          success = true;
        } catch (IOException e) {
          logger.debug("could not gossip with " + victim, e);
        }
      }

      // then try fallback cache
      if (success == false) {
        victim = fallbackCache.getRandomEntry(true);
        if (victim != null) {
          try {
            gossip(victim.getAddress(), CONNECT_TIMEOUT, false);
            success = true;
          } catch (IOException e) {
            logger.debug("could not gossip with fallback entry: " + victim, e);
          }
        }
      }

      // lastly, use bootstrap service (also wait longer on connecting)
      if (success == false) {
        if (bootstrapAddress != null) {
          try {
            gossip(bootstrapAddress, SERVER_CONNECT_TIMEOUT, true);
            success = true;
          } catch (IOException e) {
            logger.error("could not gossip with bootstrap server at " + bootstrapAddress, e);
          }
        }
      }

      synchronized (this) {
        long timeout = (long) (Math.random() * GOSSIP_TIMEOUT) + 1;

        try {
          logger.debug("waiting " + timeout + " ms");
          wait(timeout);
        } catch (InterruptedException e) {
          // IGNORE
        }
      }
    }
  }
Ejemplo n.º 4
0
  VirtualSocketAddress[] getRandomMembers(int size) {
    // use a set to get rid of duplicates
    HashSet<VirtualSocketAddress> result = new HashSet<VirtualSocketAddress>();

    ARRGCacheEntry[] entries = cache.getRandomEntries(size, false);

    for (ARRGCacheEntry entry : entries) {
      if (!entry.isArrgOnly()) {
        result.add(entry.getAddress());
      }
    }

    return result.toArray(new VirtualSocketAddress[0]);
  }
Ejemplo n.º 5
0
  private void gossip(VirtualSocketAddress victim, int timeout, boolean fillTimeout)
      throws IOException {
    long start = System.currentTimeMillis();

    if (victim == null) {
      logger.debug("no victim specified");
      return;
    }

    if (victim.equals(self.getAddress())) {
      logger.debug("not gossiping with outselves");
      return;
    }

    logger.debug("gossiping with " + victim);

    ARRGCacheEntry[] sendEntries = cache.getRandomEntries(GOSSIP_SIZE, true);

    Connection connection = null;
    try {

      connection = new Connection(victim, timeout, fillTimeout, socketFactory);

      // header

      connection.out().writeByte(Protocol.MAGIC_BYTE);
      connection.out().writeByte(Protocol.OPCODE_ARRG_GOSSIP);
      connection.out().writeUTF(poolName);

      // data

      self.writeTo(connection.out());

      connection.out().writeInt(sendEntries.length);
      for (ARRGCacheEntry entry : sendEntries) {
        entry.writeTo(connection.out());
      }

      connection.getAndCheckReply();

      ARRGCacheEntry peerEntry = new ARRGCacheEntry(connection.in());

      int receiveCount = connection.in().readInt();

      ARRGCacheEntry[] receivedEntries = new ARRGCacheEntry[receiveCount];

      for (int i = 0; i < receiveCount; i++) {
        receivedEntries[i] = new ARRGCacheEntry(connection.in());
      }

      connection.close();

      cache.add(peerEntry);
      cache.add(receivedEntries);

      resetLastGossip();

      if (statistics != null) {
        statistics.add(
            Protocol.OPCODE_ARRG_GOSSIP,
            System.currentTimeMillis() - start,
            connection.read(),
            connection.written(),
            false);
      }
    } finally {
      if (connection != null) {
        connection.close();
      }
    }
  }