/** * Not only deserialises the object, also performs adjustments on the timestamps to bring them in * alignment with the local time. Reads the current time on the peer node first. If the timestamp * of any items in the cache or commands are newer throws and IOException, because that means the * object is corrupted. Sets the timestamp of the contribution of the peer (if any) to the current * local time. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); cache = new Hashtable(); commands = new Hashtable(); final long max = in.readLong(); // the timestamp that should be maximal final long diff = System.currentTimeMillis() - max; myContribution = (ContributionBox) in.readObject(); if (myContribution != null) myContribution.timeStamp = max + diff; int cachesize = in.readInt(); for (int i = 0; i < cachesize; ++i) { ContributionBox cb = (ContributionBox) in.readObject(); if (cb.timeStamp > max) throw new IOException("corrupted timestamp in cache: " + cb.timeStamp + " " + max); cb.timeStamp += diff; cache.put(cb.contributor.name, cb); } int commandssize = in.readInt(); for (int i = 0; i < commandssize; ++i) { Object comm = in.readObject(); long time = in.readLong(); if (time > max) throw new IOException("corrupted timestamp in commands: " + time + " " + max); time += diff; commands.put(comm, new Long(time)); } }
/** * This method is the main function of the thread of the collective. It does housekeeping and * regularly talks to peers to exchange information. It can be stopped by calling <code>close() * </code>. * * @see #close() */ public final void run() { while (shouldLive) { // try{ System.gc(); removeOldStuff(); if (!refresh()) { Address[] a = observer.getPeerAddresses(); if (a != null) synchronized (cache) { for (int i = 0; i < a.length; ++i) cache.put(a[i].name, new ContributionBox(a[i], null)); } } for (int i = 0; i < REFRESHRATE; i += 1000) { try { Thread.sleep(1000); } catch (InterruptedException e) { shouldLive = false; } if (shouldLive == false) break; Thread.yield(); } /*} catch( RuntimeException e ) { Logger.error( "Collective#run()", "Runtime exception caught, something is going wrong",e); }*/ } cache = null; observer = null; }
/** Sets up parameters. */ public void setup(final EvolutionState state, final Parameter base) { if (!(state instanceof EvolutionAgent)) state.output.fatal("DRMStatistics requires an EvolutionAgent", null, null); EvolutionAgent agent = (EvolutionAgent) state; super.setup(state, base); frequency = state.parameters.getIntWithDefault(base.push(P_FREQUENCY), null, 1); store_best = state.parameters.getBoolean(base.push(P_STORE_BEST), null, true); // use_collective = state.parameters.getBoolean(base.push(P_COLLECTIVE),null,true); // If we are root, set up the base filename and the logtable if (agent.iamroot) { // I'm not sure that outputting everything to the current directory is right basefilename = System.getProperty("user.dir") + File.separator + state.parameters.getFile(base.push(P_STATISTICS_FILE), null).getName(); logtable = new Hashtable(); } else defaultlog = -3; // Maybe can be useful for recognizing it as a non valid log creationtime = System.currentTimeMillis(); }
/** * Updates local contribution and commands. Called before information exchange attempts. Uses * local address of contributor (if it is not null), this is replaced on the other side of the * communication channel by the correct global address. */ private synchronized void updateLocalInfo() { if (contributor != null) { myContribution = new ContributionBox(new Address(contributor.getName()), contributor.getContribution()); } final Long now = new Long(System.currentTimeMillis()); if (controller != null) { Set newcomms = controller.getCommands(); if (newcomms == null) return; Iterator i = newcomms.iterator(); while (i.hasNext()) commands.put(i.next(), now); } }
/** * Removes contributions and commands that are older than CONTRIBUTION_TIMEOUT and COMMAND_TIMEOUT * respectively. */ private void removeOldStuff() { final long current = System.currentTimeMillis(); synchronized (cache) { Iterator i = cache.values().iterator(); while (i.hasNext()) { ContributionBox cb = (ContributionBox) i.next(); if (current - cb.timeStamp > CONTRIBUTION_TIMEOUT) i.remove(); } } synchronized (commands) { Iterator i = commands.values().iterator(); while (i.hasNext()) { Long t = (Long) i.next(); if (current - t.longValue() > COMMAND_TIMEOUT) i.remove(); } } }
private void writeObject(ObjectOutputStream out) throws IOException { synchronized (cache) { synchronized (commands) { out.writeObject(name); // cache and commands are never null out.writeLong(System.currentTimeMillis()); out.writeObject(myContribution); out.writeInt(cache.size()); Iterator i = cache.values().iterator(); while (i.hasNext()) out.writeObject(i.next()); out.writeInt(commands.size()); i = commands.entrySet().iterator(); while (i.hasNext()) { Map.Entry e = (Map.Entry) i.next(); long time = ((Long) e.getValue()).longValue(); out.writeObject(e.getKey()); out.writeLong(time); } } } }
/** * This one checks that the stats message was received. If not, the message is sent again up to * five times. Run time an best individual of run are logged. */ public void finalStatistics(final EvolutionState state, final int result) { super.finalStatistics(state, result); EvolutionAgent agent = (EvolutionAgent) state; StatisticsData data = new StatisticsData( new Address(agent.getName()), state.generation, System.currentTimeMillis() - creationtime, getBestIndividual(state), getBestIndividual(state)); if (agent.iamroot) // Local logging printStatistics(state, data); // Every statistic will go there else { // DRM logging for (int i = 0; i < 5; i++) { // Try to send final data 5 times IRequest request = agent.fireMessage(agent.getRootAddress(), EvolutionAgent.M_STATS, data); while (request.getStatus() == IRequest.WAITING) { Thread.yield(); // try{Thread.sleep(1000);} // catch(Exception e){state.output.error("Exception: " + e);} } if (request.getStatus() == IRequest.DONE) { break; } else { state.output.error("There was an error sending final statistics."); try { Thread.sleep(1000 * i ^ 2); } catch (Exception e) { state.output.error("Exception: " + e); } } } } }