package ibis.ipl.registry.central.server; import ibis.ipl.registry.central.Member; import ibis.util.ThreadPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; final class RandomEventPusher implements Runnable { private static final int THREADS = 25; private static final Logger logger = LoggerFactory.getLogger(RandomEventPusher.class); private final Pool pool; private final long interval; /** * If true, the interval of the event pushing is adapted to the pool value */ private final boolean adaptInterval; private int currentThreads; // inner scheduling class private class Scheduler implements Runnable { Scheduler() { ThreadPool.createNew(this, "scheduler thread"); } public void run() { while (!pool.hasEnded()) { long timeout = interval; createNewThread(); if (adaptInterval) { int poolSize = pool.getSize(); if (poolSize > 1) { // divide by log2(poolSize) timeout = (long) (timeout / ((Math.log(poolSize) / Math .log(2)))); } } logger.debug("waiting " + timeout); synchronized (this) { try { wait(timeout); } catch (InterruptedException e) { // IGNORE } } } } } /** * Randomly push events to registries in the pool */ RandomEventPusher(Pool pool, long interval, boolean adaptInterval ) { this.pool = pool; this.interval = interval; this.adaptInterval = adaptInterval; currentThreads = 0; // schedules calls to our run function new Scheduler(); } private synchronized void createNewThread() { if (currentThreads >= THREADS) { logger.debug("not creating thread, maximum reached"); return; } ThreadPool.createNew(this, "node contactor"); currentThreads++; } private synchronized void threadDone() { currentThreads--; } public void run() { Member member = pool.getRandomMember(); if (member == null) { logger.debug("no member to contact"); } else { logger.debug("gossiping/pushing to " + member); pool.push(member, false, false); } threadDone(); } }