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); } }
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); } }
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); } }
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(); }
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(); } } }