Example #1
0
  synchronized void stop() {
    stopped = true;
    notifyAll();

    if (statistics != null) {
      statistics.newPoolSize(0);
      statistics.write();
    }
  }
  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);
    }
  }
  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);
    }
  }
Example #4
0
  Pool(
      IbisCapabilities capabilities,
      TypedProperties properties,
      Registry registry,
      Statistics statistics) {
    this.registry = registry;

    this.statistics = statistics;
    if (statistics != null) {
      statistics.newPoolSize(0);
    }

    if (properties.getBooleanProperty(RegistryProperties.TREE)) {
      members = new TreeMemberSet();
    } else {
      members = new ListMemberSet();
    }

    elections = new ElectionSet();
    eventList = new EventList();

    time = -1;
    initialized = false;
    closed = false;
    closeEvent = null;

    terminated = false;
    terminateEvent = null;

    stopped = false;

    // get the pool ....
    poolName = properties.getProperty(IbisProperties.POOL_NAME);
    if (poolName == null) {
      throw new IbisConfigurationException(
          "cannot initialize registry, property " + IbisProperties.POOL_NAME + " is not specified");
    }

    closedWorld = capabilities.hasCapability(IbisCapabilities.CLOSED_WORLD);

    if (closedWorld) {
      try {
        size = properties.getIntProperty(IbisProperties.POOL_SIZE);
      } catch (final NumberFormatException e) {
        throw new IbisConfigurationException(
            "could not start registry for a closed world ibis, "
                + "required property: "
                + IbisProperties.POOL_SIZE
                + " undefined",
            e);
      }
    } else {
      size = -1;
    }

    heartbeatInterval = properties.getIntProperty(RegistryProperties.HEARTBEAT_INTERVAL) * 1000;
  }
  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);
    }
  }
  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);
    }
  }
Example #7
0
  private synchronized void handleEvent(Event event) {
    logger.debug("handling event: " + event);

    switch (event.getType()) {
      case Event.JOIN:
        members.add(new Member(event.getIbis(), event));
        if (statistics != null) {
          statistics.newPoolSize(members.size());
        }
        break;
      case Event.LEAVE:
        members.remove(event.getIbis());
        if (statistics != null) {
          statistics.newPoolSize(members.size());
        }
        break;
      case Event.DIED:
        IbisIdentifier died = event.getIbis();
        members.remove(died);
        if (statistics != null) {
          statistics.newPoolSize(members.size());
        }
        if (died.equals(registry.getIbisIdentifier())) {
          logger.debug("we were declared dead");
          stop();
        }
        break;
      case Event.SIGNAL:
        // Not handled here
        break;
      case Event.ELECT:
        elections.put(new Election(event));
        if (statistics != null) {
          statistics.electionEvent();
        }
        break;
      case Event.UN_ELECT:
        elections.remove(event.getDescription());
        if (statistics != null) {
          statistics.electionEvent();
        }
        break;
      case Event.POOL_CLOSED:
        closed = true;
        closeEvent = event;
        break;
      case Event.POOL_TERMINATED:
        terminated = true;
        terminateEvent = event;
        break;
      default:
        logger.error("unknown event type: " + event.getType());
    }

    // wake up threads waiting for events
    notifyAll();

    if (logger.isDebugEnabled()) {
      logger.debug("member list now: " + members);
    }
  }
Example #8
0
  void init(DataInputStream stream) throws IOException {
    long start = System.currentTimeMillis();
    // copy over data first so we are not blocked while reading data
    byte[] bytes = new byte[stream.readInt()];
    stream.readFully(bytes);

    DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));

    long read = System.currentTimeMillis();

    // we have all the data in the array now, read from that...
    synchronized (this) {
      long locked = System.currentTimeMillis();

      if (initialized) {
        // already initialized, ignore
        return;
      }

      logger.debug("reading bootstrap state");

      time = in.readInt();

      members.init(in);

      long membersDone = System.currentTimeMillis();

      elections.init(in);
      int nrOfSignals = in.readInt();
      if (nrOfSignals < 0) {
        throw new IOException("negative number of signals");
      }

      ArrayList<Event> signals = new ArrayList<Event>();
      for (int i = 0; i < nrOfSignals; i++) {
        signals.add(new Event(in));
      }

      closed = in.readBoolean();
      if (closed) {
        closeEvent = new Event(in);
      }

      terminated = in.readBoolean();
      if (terminated) {
        terminateEvent = new Event(in);
      }

      // Create list of "old" events

      SortedSet<Event> events = new TreeSet<Event>();
      events.addAll(members.getJoinEvents());
      events.addAll(elections.getEvents());
      events.addAll(signals);
      if (closed) {
        events.add(closeEvent);
      }
      if (terminated) {
        events.add(terminateEvent);
      }

      long used = System.currentTimeMillis();

      // pass old events to the registry
      // CALLS REGISTRY WHILE POOL IS LOCKED!
      for (Event event : events) {
        registry.handleEvent(event);
      }

      long handled = System.currentTimeMillis();

      initialized = true;
      notifyAll();

      if (statistics != null) {
        statistics.newPoolSize(members.size());
      }
      long statted = System.currentTimeMillis();

      logger.info(
          "pool init, read = "
              + (read - start)
              + ", locked = "
              + (locked - read)
              + ", membersDone = "
              + (membersDone - locked)
              + ", used = "
              + (used - membersDone)
              + ", handled = "
              + (handled - used)
              + ", statted = "
              + (statted - handled));
    }

    handleEvents();
    logger.debug("bootstrap complete");
  }
  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();
  }
Example #10
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();
      }
    }
  }