예제 #1
0
  public void ping(IbisIdentifier ibis) throws IOException {
    long start = System.currentTimeMillis();
    Connection connection =
        new Connection(ibis, CONNECTION_TIMEOUT, true, socketFactory, Protocol.VIRTUAL_PORT);

    connection.out().writeByte(Protocol.MAGIC_BYTE);
    connection.out().writeByte(Protocol.OPCODE_PING);

    connection.getAndCheckReply();
    IbisIdentifier result = new IbisIdentifier(connection.in());

    connection.close();

    if (!result.equals(ibis)) {
      throw new IOException("tried to ping " + ibis + ", reached " + result + " instead");
    }
    if (statistics != null) {
      statistics.add(
          Protocol.OPCODE_PING,
          System.currentTimeMillis() - start,
          connection.read(),
          connection.written(),
          false);
    }
  }
예제 #2
0
  void sendLeave(VirtualSocketAddress address) {
    if (address.equals(serverSocket.getLocalSocketAddress())) {
      // do not connect to self
      return;
    }

    try {
      long start = System.currentTimeMillis();
      Connection connection =
          new Connection(address, LEAVE_CONNECTION_TIMEOUT, true, socketFactory);

      connection.out().writeByte(Protocol.MAGIC_BYTE);
      connection.out().writeByte(Protocol.OPCODE_LEAVE);
      registry.getIbisIdentifier().writeTo(connection.out());

      connection.getAndCheckReply();

      connection.close();
      if (statistics != null) {
        statistics.add(
            Protocol.OPCODE_LEAVE,
            System.currentTimeMillis() - start,
            connection.read(),
            connection.written(),
            false);
      }
    } catch (IOException e) {
      logger.debug(serverSocket.getLocalSocketAddress() + " could not send leave to " + address);
    }
  }
예제 #3
0
  public void sendSignals(String signal, IbisIdentifier[] ibises) throws IOException {
    String errorMessage = null;

    for (IbisIdentifier ibis : ibises) {
      try {
        long start = System.currentTimeMillis();
        Connection connection =
            new Connection(ibis, CONNECTION_TIMEOUT, true, socketFactory, Protocol.VIRTUAL_PORT);

        connection.out().writeByte(Protocol.MAGIC_BYTE);
        connection.out().writeByte(Protocol.OPCODE_SIGNAL);
        registry.getIbisIdentifier().writeTo(connection.out());
        connection.out().writeUTF(signal);

        connection.getAndCheckReply();

        connection.close();
        if (statistics != null) {
          statistics.add(
              Protocol.OPCODE_SIGNAL,
              System.currentTimeMillis() - start,
              connection.read(),
              connection.written(),
              false);
        }
      } catch (IOException e) {
        logger.error("could not send signal to " + ibis);
        if (errorMessage == null) {
          errorMessage = "could not send signal to: " + ibis;
        } else {
          errorMessage += ", " + ibis;
        }
      }
    }
    if (errorMessage != null) {
      throw new IOException(errorMessage);
    }
  }
예제 #4
0
  public void gossip() {
    VirtualSocketAddress address = arrg.getRandomMember();

    if (address == null || address.equals(serverSocket.getLocalSocketAddress())) {
      logger.debug("noone to gossip with, or (not) gossiping with self");
      return;
    }

    try {
      long start = System.currentTimeMillis();
      Connection connection = new Connection(address, CONNECTION_TIMEOUT, true, socketFactory);

      connection.out().writeByte(Protocol.MAGIC_BYTE);
      connection.out().writeByte(Protocol.OPCODE_GOSSIP);
      registry.getIbisIdentifier().writeTo(connection.out());

      pool.writeGossipData(connection.out(), gossipSize);
      elections.writeGossipData(connection.out());

      connection.getAndCheckReply();

      pool.readGossipData(connection.in());
      elections.readGossipData(connection.in());

      connection.close();
      if (statistics != null) {
        statistics.add(
            Protocol.OPCODE_GOSSIP,
            System.currentTimeMillis() - start,
            connection.read(),
            connection.written(),
            false);
      }
    } catch (IOException e) {
      logger.debug("could not gossip with " + address, e);
    }
  }
예제 #5
0
  public void run() {
    Connection connection = null;
    try {
      logger.debug("accepting connection");
      connection = new Connection(serverSocket);
      logger.debug("connection accepted");
    } catch (IOException e) {
      if (registry.isStopped()) {
        threadEnded();
        return;
      }
      logger.error("Accept failed, waiting a second, will retry", e);

      // wait a bit
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e1) {
        // IGNORE
      }
    }

    // create new thread for next connection
    createThread();

    if (connection == null) {
      threadEnded();
      return;
    }

    long start = System.currentTimeMillis();
    byte opcode = 0;
    try {
      byte magic = connection.in().readByte();

      if (magic != Protocol.MAGIC_BYTE) {
        throw new IOException("Invalid header byte in accepting connection");
      }

      opcode = connection.in().readByte();

      if (logger.isDebugEnabled()) {
        logger.debug("got request, opcode = " + Protocol.opcodeString(opcode));
      }

      switch (opcode) {
        case Protocol.OPCODE_ARRG_GOSSIP:
          handleArrgGossip(connection);
          break;
        case Protocol.OPCODE_SIGNAL:
          handleSignal(connection);
          break;
        case Protocol.OPCODE_LEAVE:
          handleLeave(connection);
          break;
        case Protocol.OPCODE_GOSSIP:
          handleGossip(connection);
          break;
        case Protocol.OPCODE_PING:
          handlePing(connection);
          break;
        default:
          logger.error("unknown opcode: " + opcode);
      }
    } catch (IOException e) {
      logger.error("error on handling connection", e);
    } finally {
      connection.close();
    }

    logger.debug("done handling request");

    if (statistics != null) {
      statistics.add(
          opcode,
          System.currentTimeMillis() - start,
          connection.read(),
          connection.written(),
          true);
    }
    threadEnded();
  }
예제 #6
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();
      }
    }
  }