From a5ab6f576d98d5199af4ff4e26ac568f51eca649 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Sat, 31 Jan 2009 14:22:07 +0000 Subject: [PATCH] * SimpleScheduler: New replacement for SimpleTimer when events will not be rescheduled or cancelled, to reduce SimpleTimer lock contention --- .../src/org/klomp/snark/I2PSnarkUtil.java | 3 +- .../org/klomp/snark/PeerConnectionOut.java | 3 +- .../i2p/i2ptunnel/I2PTunnelClientBase.java | 3 +- .../net/i2p/client/streaming/Connection.java | 9 +- .../client/streaming/ConnectionHandler.java | 3 +- .../streaming/ConnectionPacketHandler.java | 3 +- .../src/net/i2p/apps/systray/SysTray.java | 4 +- .../src/net/i2p/client/I2PSessionImpl.java | 3 +- .../crypto/TransientSessionKeyManager.java | 4 +- core/java/src/net/i2p/util/ByteCache.java | 3 +- .../src/net/i2p/util/SimpleScheduler.java | 164 ++++++++++++++++++ router/java/src/net/i2p/router/Router.java | 7 +- .../router/client/ClientConnectionRunner.java | 3 +- .../i2p/router/peermanager/PeerManager.java | 5 +- .../transport/udp/EstablishmentManager.java | 9 +- .../router/transport/udp/PeerTestManager.java | 9 +- .../i2p/router/transport/udp/UDPReceiver.java | 3 +- .../router/transport/udp/UDPTransport.java | 3 +- 18 files changed, 207 insertions(+), 34 deletions(-) create mode 100644 core/java/src/net/i2p/util/SimpleScheduler.java diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index f014580ec..26ed5860f 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -24,6 +24,7 @@ import net.i2p.data.Destination; import net.i2p.data.Hash; import net.i2p.util.EepGet; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -183,7 +184,7 @@ public class I2PSnarkUtil { synchronized (_shitlist) { _shitlist.add(dest); } - SimpleTimer.getInstance().addEvent(new Unshitlist(dest), 10*60*1000); + SimpleScheduler.getInstance().addEvent(new Unshitlist(dest), 10*60*1000); throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage()); } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java index 8fed9577a..1a53c342f 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java @@ -28,6 +28,7 @@ import java.util.List; import net.i2p.util.I2PAppThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; class PeerConnectionOut implements Runnable @@ -215,7 +216,7 @@ class PeerConnectionOut implements Runnable private void addMessage(Message m) { if (m.type == Message.PIECE) - SimpleTimer.getInstance().addEvent(new RemoveTooSlow(m), SEND_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new RemoveTooSlow(m), SEND_TIMEOUT); synchronized(sendQueue) { sendQueue.add(m); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java index d6e5bf9f9..38311eaf1 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java @@ -27,6 +27,7 @@ import net.i2p.data.Destination; import net.i2p.util.EventDispatcher; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runnable { @@ -401,7 +402,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna } if (_maxWaitTime > 0) - SimpleTimer.getInstance().addEvent(new CloseEvent(s), _maxWaitTime); + SimpleScheduler.getInstance().addEvent(new CloseEvent(s), _maxWaitTime); synchronized (_waitingSockets) { _waitingSockets.add(s); diff --git a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java index 85872e9c5..ee93d20ee 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java @@ -12,6 +12,7 @@ import net.i2p.client.I2PSession; import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -246,7 +247,7 @@ public class Connection { void sendReset() { if (_disconnectScheduledOn < 0) { _disconnectScheduledOn = _context.clock().now(); - SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); } long now = _context.clock().now(); if (_resetSentOn + 10*1000 > now) return; // don't send resets too fast @@ -460,7 +461,7 @@ public class Connection { void resetReceived() { if (_disconnectScheduledOn < 0) { _disconnectScheduledOn = _context.clock().now(); - SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); } _resetReceived = true; MessageOutputStream mos = _outputStream; @@ -509,7 +510,7 @@ public class Connection { if (removeFromConMgr) { if (_disconnectScheduledOn < 0) { _disconnectScheduledOn = _context.clock().now(); - SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); } } _connected = false; @@ -708,7 +709,7 @@ public class Connection { _closeSentOn = when; if (_disconnectScheduledOn < 0) { _disconnectScheduledOn = _context.clock().now(); - SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); } } public long getCloseReceivedOn() { return _closeReceivedOn; } diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java index 7d1d4827f..a123708e4 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java @@ -5,6 +5,7 @@ import java.util.List; import net.i2p.I2PAppContext; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -54,7 +55,7 @@ class ConnectionHandler { } if (_log.shouldLog(Log.DEBUG)) _log.debug("Receive new SYN: " + packet + ": timeout in " + _acceptTimeout); - RetransmissionTimer.getInstance().addEvent(new TimeoutSyn(packet), _acceptTimeout); + SimpleScheduler.getInstance().addEvent(new TimeoutSyn(packet), _acceptTimeout); synchronized (_synQueue) { _synQueue.add(packet); _synQueue.notifyAll(); diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java index 7c445f038..f7b245cb8 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java @@ -7,6 +7,7 @@ import net.i2p.I2PException; import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -168,7 +169,7 @@ public class ConnectionPacketHandler { // take note of congestion if (_log.shouldLog(Log.WARN)) _log.warn("congestion.. dup " + packet); - RetransmissionTimer.getInstance().addEvent(new AckDup(con), con.getOptions().getSendAckDelay()); + SimpleScheduler.getInstance().addEvent(new AckDup(con), con.getOptions().getSendAckDelay()); //con.setNextSendTime(_context.clock().now() + con.getOptions().getSendAckDelay()); //fastAck = true; } else { diff --git a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java index 380c5b172..4a635fd08 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java +++ b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java @@ -11,6 +11,7 @@ package net.i2p.apps.systray; import java.awt.Frame; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; import snoozesoft.systray4j.SysTrayMenu; import snoozesoft.systray4j.SysTrayMenuEvent; @@ -60,14 +61,13 @@ public class SysTray implements SysTrayMenuListener { private SysTray() { _sysTrayMenuIcon.addSysTrayMenuListener(this); createSysTrayMenu(); - SimpleTimer.getInstance().addEvent(new RefreshDisplayEvent(), REFRESH_DISPLAY_FREQUENCY); + SimpleScheduler.getInstance().addPeriodicEvent(new RefreshDisplayEvent(), REFRESH_DISPLAY_FREQUENCY); } private static final long REFRESH_DISPLAY_FREQUENCY = 30*1000; private class RefreshDisplayEvent implements SimpleTimer.TimedEvent { public void timeReached() { refreshDisplay(); - SimpleTimer.getInstance().addEvent(RefreshDisplayEvent.this, REFRESH_DISPLAY_FREQUENCY); } } diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index a57957107..d4ff7360a 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -40,6 +40,7 @@ import net.i2p.data.i2cp.MessagePayloadMessage; import net.i2p.data.i2cp.SessionId; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -369,7 +370,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Notified availability for session " + _sessionId + ", message " + id); } - SimpleTimer.getInstance().addEvent(new VerifyUsage(mid), 30*1000); + SimpleScheduler.getInstance().addEvent(new VerifyUsage(mid), 30*1000); } private class VerifyUsage implements SimpleTimer.TimedEvent { private Long _msgId; diff --git a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java index 1b160f8dd..0d71677a9 100644 --- a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java +++ b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java @@ -24,6 +24,7 @@ import net.i2p.data.PublicKey; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -70,7 +71,7 @@ class TransientSessionKeyManager extends SessionKeyManager { _inboundTagSets = new HashMap(1024); context.statManager().createRateStat("crypto.sessionTagsExpired", "How many tags/sessions are expired?", "Encryption", new long[] { 10*60*1000, 60*60*1000, 3*60*60*1000 }); context.statManager().createRateStat("crypto.sessionTagsRemaining", "How many tags/sessions are remaining after a cleanup?", "Encryption", new long[] { 10*60*1000, 60*60*1000, 3*60*60*1000 }); - SimpleTimer.getInstance().addEvent(new CleanupEvent(), 60*1000); + SimpleScheduler.getInstance().addPeriodicEvent(new CleanupEvent(), 60*1000); } private TransientSessionKeyManager() { this(null); } @@ -80,7 +81,6 @@ class TransientSessionKeyManager extends SessionKeyManager { int expired = aggressiveExpire(); long expireTime = _context.clock().now() - beforeExpire; _context.statManager().addRateData("crypto.sessionTagsExpired", expired, expireTime); - SimpleTimer.getInstance().addEvent(CleanupEvent.this, 60*1000); } } diff --git a/core/java/src/net/i2p/util/ByteCache.java b/core/java/src/net/i2p/util/ByteCache.java index aadc721aa..4bd3da6ef 100644 --- a/core/java/src/net/i2p/util/ByteCache.java +++ b/core/java/src/net/i2p/util/ByteCache.java @@ -55,7 +55,7 @@ public final class ByteCache { _maxCached = maxCachedEntries; _entrySize = entrySize; _lastOverflow = -1; - SimpleTimer.getInstance().addEvent(new Cleanup(), CLEANUP_FREQUENCY); + SimpleScheduler.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY); _log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class); } @@ -120,7 +120,6 @@ public final class ByteCache { _log.debug("Removing " + toRemove + " cached entries of size " + _entrySize); } } - SimpleTimer.getInstance().addEvent(Cleanup.this, CLEANUP_FREQUENCY); } } } diff --git a/core/java/src/net/i2p/util/SimpleScheduler.java b/core/java/src/net/i2p/util/SimpleScheduler.java new file mode 100644 index 000000000..91415102c --- /dev/null +++ b/core/java/src/net/i2p/util/SimpleScheduler.java @@ -0,0 +1,164 @@ +package net.i2p.util; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadFactory; + +import net.i2p.I2PAppContext; + +/** + * Simple event scheduler - toss an event on the queue and it gets fired at the + * appropriate time. The method that is fired however should NOT block (otherwise + * they b0rk the timer). + * + * This is like SimpleScheduler but addEvent() for an existing event adds a second + * job. Events cannot be cancelled or rescheduled. + * + * For events that cannot or will not be cancelled or rescheduled - + * for example, a call such as: + * SimpleTimer.getInstance().addEvent(new FooEvent(bar), timeoutMs); + * use SimpleScheduler instead to reduce lock contention in SimpleTimer... + * + * For periodic events, use addPeriodicEvent(). Unlike SimpleTimer, + * uncaught Exceptions will not prevent subsequent executions. + * + * @author zzz + */ +public class SimpleScheduler { + private static final SimpleScheduler _instance = new SimpleScheduler(); + public static SimpleScheduler getInstance() { return _instance; } + private static final int THREADS = 4; + private I2PAppContext _context; + private Log _log; + private ScheduledThreadPoolExecutor _executor; + private String _name; + private int _count; + + protected SimpleScheduler() { this("SimpleScheduler"); } + protected SimpleScheduler(String name) { + _context = I2PAppContext.getGlobalContext(); + _log = _context.logManager().getLog(SimpleScheduler.class); + _name = name; + _count = 0; + _executor = new ScheduledThreadPoolExecutor(THREADS, new CustomThreadFactory()); + } + + /** + * Removes the SimpleScheduler. + */ + public void stop() { + _executor.shutdownNow(); + } + + /** + * Queue up the given event to be fired no sooner than timeoutMs from now. + * + * @param event + * @param timeoutMs + */ + public void addEvent(SimpleTimer.TimedEvent event, long timeoutMs) { + if (event == null) + throw new IllegalArgumentException("addEvent null"); + RunnableEvent re = new RunnableEvent(event, timeoutMs); + re.schedule(); + } + + public void addPeriodicEvent(SimpleTimer.TimedEvent event, long timeoutMs) { + addPeriodicEvent(event, timeoutMs, timeoutMs); + } + + /** + * Queue up the given event to be fired after initialDelay and every + * timeoutMs thereafter. The TimedEvent must not do its own rescheduling. + * As all Exceptions are caught in run(), these will not prevent + * subsequent executions (unlike SimpleTimer, where the TimedEvent does + * its own rescheduling) + * + * @param event + * @param initialDelay (ms) + * @param timeoutMs + */ + public void addPeriodicEvent(SimpleTimer.TimedEvent event, long initialDelay, long timeoutMs) { + if (event == null) + throw new IllegalArgumentException("addEvent null"); + RunnableEvent re = new PeriodicRunnableEvent(event, initialDelay, timeoutMs); + re.schedule(); + } + + private class CustomThreadFactory implements ThreadFactory { + public Thread newThread(Runnable r) { + Thread rv = Executors.defaultThreadFactory().newThread(r); + rv.setName(_name + ' ' + (++_count) + '/' + THREADS); + rv.setDaemon(true); + return rv; + } + } + + /** + * Same as SimpleTimer.TimedEvent but use run() instead of timeReached(), and remembers the time + */ + private class RunnableEvent implements Runnable { + protected SimpleTimer.TimedEvent _timedEvent; + protected long _scheduled; + + public RunnableEvent(SimpleTimer.TimedEvent t, long timeoutMs) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Creating w/ delay " + timeoutMs + " : " + t); + _timedEvent = t; + _scheduled = timeoutMs + System.currentTimeMillis(); + } + public void schedule() { + _executor.schedule(this, _scheduled - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } + public void run() { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Running: " + _timedEvent); + long before = System.currentTimeMillis(); + if (_log.shouldLog(Log.WARN) && before < _scheduled - 100) + _log.warn(_name + " wtf, early execution " + (_scheduled - before) + ": " + _timedEvent); + else if (_log.shouldLog(Log.WARN) && before > _scheduled + 1000) + _log.warn(" wtf, late execution " + (before - _scheduled) + ": " + _timedEvent + debug()); + try { + _timedEvent.timeReached(); + } catch (Throwable t) { + _log.log(Log.CRIT, _name + " wtf, event borked: " + _timedEvent, t); + } + long time = System.currentTimeMillis() - before; + if (time > 1000 && _log.shouldLog(Log.WARN)) + _log.warn(_name + " wtf, event execution took " + time + ": " + _timedEvent); + long completed = _executor.getCompletedTaskCount(); + if (_log.shouldLog(Log.INFO) && completed % 250 == 0) + _log.info(debug()); + } + } + + /** Run every timeoutMs. TimedEvent must not do its own reschedule via addEvent() */ + private class PeriodicRunnableEvent extends RunnableEvent { + private long _timeoutMs; + private long _initialDelay; + public PeriodicRunnableEvent(SimpleTimer.TimedEvent t, long initialDelay, long timeoutMs) { + super(t, timeoutMs); + _initialDelay = initialDelay; + _timeoutMs = timeoutMs; + _scheduled = initialDelay + System.currentTimeMillis(); + } + public void schedule() { + _executor.scheduleWithFixedDelay(this, _initialDelay, _timeoutMs, TimeUnit.MILLISECONDS); + } + public void run() { + super.run(); + _scheduled = _timeoutMs + System.currentTimeMillis(); + } + } + + private String debug() { + return + " Pool: " + _name + + " Active: " + _executor.getActiveCount() + '/' + _executor.getPoolSize() + + " Completed: " + _executor.getCompletedTaskCount() + + " Queued: " + _executor.getQueue().size(); + } +} + diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index f7342413a..033678924 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -43,6 +43,7 @@ import net.i2p.stat.StatManager; import net.i2p.util.FileUtil; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -257,7 +258,7 @@ public class Router { _context.inNetMessagePool().startup(); startupQueue(); //_context.jobQueue().addJob(new CoalesceStatsJob(_context)); - SimpleTimer.getInstance().addEvent(new CoalesceStatsEvent(_context), 0); + SimpleScheduler.getInstance().addPeriodicEvent(new CoalesceStatsEvent(_context), 20*1000); _context.jobQueue().addJob(new UpdateRoutingKeyModifierJob(_context)); warmupCrypto(); _sessionKeyPersistenceHelper.startup(); @@ -346,7 +347,7 @@ public class Router { if (blockingRebuild) r.timeReached(); else - SimpleTimer.getInstance().addEvent(r, 0); + SimpleScheduler.getInstance().addEvent(r, 0); } catch (DataFormatException dfe) { _log.log(Log.CRIT, "Internal error - unable to sign our own address?!", dfe); } @@ -1261,8 +1262,6 @@ class CoalesceStatsEvent implements SimpleTimer.TimedEvent { getContext().statManager().addRateData("bw.sendBps", (long)KBps, 60*1000); } } - - SimpleTimer.getInstance().addEvent(this, 20*1000); } } diff --git a/router/java/src/net/i2p/router/client/ClientConnectionRunner.java b/router/java/src/net/i2p/router/client/ClientConnectionRunner.java index 133ad142c..189568ead 100644 --- a/router/java/src/net/i2p/router/client/ClientConnectionRunner.java +++ b/router/java/src/net/i2p/router/client/ClientConnectionRunner.java @@ -38,6 +38,7 @@ import net.i2p.router.RouterContext; import net.i2p.util.I2PThread; import net.i2p.util.Log; import net.i2p.util.RandomSource; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -419,7 +420,7 @@ public class ClientConnectionRunner { // theirs is newer } else { // ours is newer, so wait a few secs and retry - SimpleTimer.getInstance().addEvent(new Rerequest(set, expirationTime, onCreateJob, onFailedJob), 3*1000); + SimpleScheduler.getInstance().addEvent(new Rerequest(set, expirationTime, onCreateJob, onFailedJob), 3*1000); } // fire onCreated? return; // already requesting diff --git a/router/java/src/net/i2p/router/peermanager/PeerManager.java b/router/java/src/net/i2p/router/peermanager/PeerManager.java index b2b16a00d..1c265ee67 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerManager.java +++ b/router/java/src/net/i2p/router/peermanager/PeerManager.java @@ -24,6 +24,7 @@ import net.i2p.router.PeerSelectionCriteria; import net.i2p.router.RouterContext; import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -50,7 +51,7 @@ class PeerManager { _peersByCapability[i] = new ArrayList(64); loadProfiles(); ////_context.jobQueue().addJob(new EvaluateProfilesJob(_context)); - SimpleTimer.getInstance().addEvent(new Reorg(), 0); + SimpleScheduler.getInstance().addPeriodicEvent(new Reorg(), 0, 30*1000); //_context.jobQueue().addJob(new PersistProfilesJob(_context, this)); } @@ -60,8 +61,6 @@ class PeerManager { _organizer.reorganize(true); } catch (Throwable t) { _log.log(Log.CRIT, "Error evaluating profiles", t); - } finally { - SimpleTimer.getInstance().addEvent(Reorg.this, 30*1000); } } } diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index 6ab159408..896fe1ce4 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -22,6 +22,7 @@ import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -184,7 +185,7 @@ public class EstablishmentManager { msg.getTarget().getIdentity(), new SessionKey(addr.getIntroKey()), addr); _outboundStates.put(to, state); - SimpleTimer.getInstance().addEvent(new Expire(to, state), 10*1000); + SimpleScheduler.getInstance().addEvent(new Expire(to, state), 10*1000); } } if (state != null) { @@ -394,7 +395,7 @@ public class EstablishmentManager { msg.getTarget().getIdentity(), new SessionKey(addr.getIntroKey()), addr); _outboundStates.put(to, qstate); - SimpleTimer.getInstance().addEvent(new Expire(to, qstate), 10*1000); + SimpleScheduler.getInstance().addEvent(new Expire(to, qstate), 10*1000); for (int i = 0; i < queued.size(); i++) { OutNetMessage m = (OutNetMessage)queued.get(i); @@ -477,7 +478,7 @@ public class EstablishmentManager { dsm.setMessageExpiration(_context.clock().now()+10*1000); dsm.setMessageId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE)); _transport.send(dsm, peer); - SimpleTimer.getInstance().addEvent(new PublishToNewInbound(peer), 0); + SimpleScheduler.getInstance().addEvent(new PublishToNewInbound(peer), 0); } private class PublishToNewInbound implements SimpleTimer.TimedEvent { private PeerState _peer; @@ -629,7 +630,7 @@ public class EstablishmentManager { } } } - SimpleTimer.getInstance().addEvent(new FailIntroduction(state, nonce), INTRO_ATTEMPT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new FailIntroduction(state, nonce), INTRO_ATTEMPT_TIMEOUT); state.setIntroNonce(nonce); _context.statManager().addRateData("udp.sendIntroRelayRequest", 1, 0); UDPPacket requests[] = _builder.buildRelayRequest(_transport, state, _transport.getIntroKey()); diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java index 7aa3c2fa1..35c5511be 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java @@ -15,6 +15,7 @@ import net.i2p.data.SessionKey; import net.i2p.router.CommSystemFacade; import net.i2p.router.RouterContext; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -79,7 +80,7 @@ class PeerTestManager { sendTestToBob(); - SimpleTimer.getInstance().addEvent(new ContinueTest(), RESEND_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new ContinueTest(), RESEND_TIMEOUT); } private class ContinueTest implements SimpleTimer.TimedEvent { @@ -103,7 +104,7 @@ class PeerTestManager { // second message from Charlie yet sendTestToCharlie(); } - SimpleTimer.getInstance().addEvent(ContinueTest.this, RESEND_TIMEOUT); + SimpleScheduler.getInstance().addEvent(ContinueTest.this, RESEND_TIMEOUT); } } } @@ -430,7 +431,7 @@ class PeerTestManager { synchronized (_activeTests) { _activeTests.put(new Long(nonce), state); } - SimpleTimer.getInstance().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); + SimpleScheduler.getInstance().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); } UDPPacket packet = _packetBuilder.buildPeerTestToBob(bobIP, from.getPort(), aliceIP, alicePort, aliceIntroKey, nonce, state.getBobCipherKey(), state.getBobMACKey()); @@ -511,7 +512,7 @@ class PeerTestManager { synchronized (_activeTests) { _activeTests.put(new Long(nonce), state); } - SimpleTimer.getInstance().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); + SimpleScheduler.getInstance().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); } UDPPacket packet = _packetBuilder.buildPeerTestToCharlie(aliceIP, from.getPort(), aliceIntroKey, nonce, diff --git a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java index 10876a0e7..3535484c9 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java @@ -9,6 +9,7 @@ import net.i2p.router.RouterContext; import net.i2p.router.transport.FIFOBandwidthLimiter; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -115,7 +116,7 @@ public class UDPReceiver { long delay = ARTIFICIAL_DELAY_BASE + _context.random().nextInt(ARTIFICIAL_DELAY); if (_log.shouldLog(Log.INFO)) _log.info("Delay packet " + packet + " for " + delay); - SimpleTimer.getInstance().addEvent(new ArtificiallyDelayedReceive(packet), delay); + SimpleScheduler.getInstance().addEvent(new ArtificiallyDelayedReceive(packet), delay); return -1; } diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index 03714d7ef..e5185defa 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -33,6 +33,7 @@ import net.i2p.router.transport.Transport; import net.i2p.router.transport.TransportBid; import net.i2p.router.transport.TransportImpl; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -631,7 +632,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } if (added) { _context.statManager().addRateData("udp.dropPeerDroplist", droplistSize, 0); - SimpleTimer.getInstance().addEvent(new RemoveDropList(remote), DROPLIST_PERIOD); + SimpleScheduler.getInstance().addEvent(new RemoveDropList(remote), DROPLIST_PERIOD); } } markUnreachable(peerHash); -- GitLab