From 1e729bae1ca3654e50a7534b577c835e76fd5fc1 Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Sun, 20 Sep 2020 17:49:07 +0100 Subject: [PATCH] implement forgetting of hopeless hosts after some time --- .../groovy/com/muwire/core/MuWireSettings.groovy | 4 +++- .../groovy/com/muwire/core/hostcache/Host.groovy | 11 +++++++++-- .../com/muwire/core/hostcache/HostCache.groovy | 12 ++++++++---- .../com/muwire/core/hostcache/HostCacheTest.groovy | 10 ++++++++++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/MuWireSettings.groovy b/core/src/main/groovy/com/muwire/core/MuWireSettings.groovy index 3760bf24..913b8652 100644 --- a/core/src/main/groovy/com/muwire/core/MuWireSettings.groovy +++ b/core/src/main/groovy/com/muwire/core/MuWireSettings.groovy @@ -50,7 +50,7 @@ class MuWireSettings { File chatWelcomeFile Set watchedDirectories float downloadSequentialRatio - int hostClearInterval, hostHopelessInterval, hostRejectInterval + int hostClearInterval, hostHopelessInterval, hostRejectInterval, hostHopelessPurgeInterval int meshExpiration int speedSmoothSeconds boolean embeddedRouter @@ -88,6 +88,7 @@ class MuWireSettings { hostClearInterval = Integer.valueOf(props.getProperty("hostClearInterval","15")) hostHopelessInterval = Integer.valueOf(props.getProperty("hostHopelessInterval", "1440")) hostRejectInterval = Integer.valueOf(props.getProperty("hostRejectInterval", "1")) + hostHopelessPurgeInterval = Integer.valueOf(props.getProperty("hostHopelessPurgeInterval","2880")) meshExpiration = Integer.valueOf(props.getProperty("meshExpiration","60")) embeddedRouter = Boolean.valueOf(props.getProperty("embeddedRouter","false")) plugin = Boolean.valueOf(props.getProperty("plugin","false")) @@ -158,6 +159,7 @@ class MuWireSettings { props.setProperty("hostClearInterval", String.valueOf(hostClearInterval)) props.setProperty("hostHopelessInterval", String.valueOf(hostHopelessInterval)) props.setProperty("hostRejectInterval", String.valueOf(hostRejectInterval)) + props.setProperty("hostHopelessPurgeInterval", String.valueOf(hostHopelessPurgeInterval)) props.setProperty("meshExpiration", String.valueOf(meshExpiration)) props.setProperty("embeddedRouter", String.valueOf(embeddedRouter)) props.setProperty("plugin", String.valueOf(plugin)) diff --git a/core/src/main/groovy/com/muwire/core/hostcache/Host.groovy b/core/src/main/groovy/com/muwire/core/hostcache/Host.groovy index 9b77c74d..cd218468 100644 --- a/core/src/main/groovy/com/muwire/core/hostcache/Host.groovy +++ b/core/src/main/groovy/com/muwire/core/hostcache/Host.groovy @@ -7,17 +7,19 @@ class Host { private static final int MAX_FAILURES = 3 final Destination destination - private final int clearInterval, hopelessInterval, rejectionInterval + private final int clearInterval, hopelessInterval, rejectionInterval, purgeInterval int failures,successes long lastAttempt long lastSuccessfulAttempt long lastRejection - public Host(Destination destination, int clearInterval, int hopelessInterval, int rejectionInterval) { + public Host(Destination destination, int clearInterval, int hopelessInterval, int rejectionInterval, + int purgeInterval) { this.destination = destination this.clearInterval = clearInterval this.hopelessInterval = hopelessInterval this.rejectionInterval = rejectionInterval + this.purgeInterval = purgeInterval } private void connectSuccessful() { @@ -67,4 +69,9 @@ class Host { synchronized boolean isRecentlyRejected(final long now) { now - lastRejection < (rejectionInterval * 60 * 1000) } + + synchronized boolean shouldBeForgotten(final long now) { + isHopeless(now) && + now - lastAttempt > (purgeInterval * 60 * 1000) + } } diff --git a/core/src/main/groovy/com/muwire/core/hostcache/HostCache.groovy b/core/src/main/groovy/com/muwire/core/hostcache/HostCache.groovy index 265af706..143918e7 100644 --- a/core/src/main/groovy/com/muwire/core/hostcache/HostCache.groovy +++ b/core/src/main/groovy/com/muwire/core/hostcache/HostCache.groovy @@ -52,7 +52,8 @@ class HostCache extends Service { hosts.get(e.destination).clearFailures() return } - Host host = new Host(e.destination, settings.hostClearInterval, settings.hostHopelessInterval, settings.hostRejectInterval) + Host host = new Host(e.destination, settings.hostClearInterval, settings.hostHopelessInterval, + settings.hostRejectInterval, settings.hostHopelessPurgeInterval) if (allowHost(host)) { hosts.put(e.destination, host) } @@ -64,7 +65,8 @@ class HostCache extends Service { Destination dest = e.endpoint.destination Host host = hosts.get(dest) if (host == null) { - host = new Host(dest, settings.hostClearInterval, settings.hostHopelessInterval, settings.hostRejectInterval) + host = new Host(dest, settings.hostClearInterval, settings.hostHopelessInterval, + settings.hostRejectInterval, settings.hostHopelessPurgeInterval) hosts.put(dest, host) } @@ -130,7 +132,8 @@ class HostCache extends Service { storage.eachLine { def entry = slurper.parseText(it) Destination dest = new Destination(entry.destination) - Host host = new Host(dest, settings.hostClearInterval, settings.hostHopelessInterval, settings.hostRejectInterval) + Host host = new Host(dest, settings.hostClearInterval, settings.hostHopelessInterval, + settings.hostRejectInterval, settings.hostHopelessPurgeInterval) host.failures = Integer.valueOf(String.valueOf(entry.failures)) host.successes = Integer.valueOf(String.valueOf(entry.successes)) if (entry.lastAttempt != null) @@ -163,8 +166,9 @@ class HostCache extends Service { } private void save() { - storage.delete() final long now = System.currentTimeMillis() + hosts.keySet().removeAll { hosts[it].shouldBeForgotten(now) } + storage.delete() storage.withPrintWriter { writer -> hosts.each { dest, host -> if (allowHost(host) && !host.isHopeless(now)) { diff --git a/core/src/test/groovy/com/muwire/core/hostcache/HostCacheTest.groovy b/core/src/test/groovy/com/muwire/core/hostcache/HostCacheTest.groovy index e05eac99..5b33ae9e 100644 --- a/core/src/test/groovy/com/muwire/core/hostcache/HostCacheTest.groovy +++ b/core/src/test/groovy/com/muwire/core/hostcache/HostCacheTest.groovy @@ -75,6 +75,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() @@ -97,6 +98,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() @@ -114,6 +116,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() @@ -136,6 +139,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() cache.onHostDiscoveredEvent(new HostDiscoveredEvent(destination: destinations.dest1)) @@ -160,6 +164,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 100 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() cache.onHostDiscoveredEvent(new HostDiscoveredEvent(destination: destinations.dest1)) @@ -182,6 +187,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() cache.onHostDiscoveredEvent(new HostDiscoveredEvent(destination: destinations.dest1)) @@ -211,6 +217,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() cache.onHostDiscoveredEvent(new HostDiscoveredEvent(destination: destinations.dest1)) @@ -246,6 +253,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() cache.onHostDiscoveredEvent(new HostDiscoveredEvent(destination: destinations.dest1)) @@ -266,6 +274,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() cache.onHostDiscoveredEvent(new HostDiscoveredEvent(destination: destinations.dest1)) @@ -301,6 +310,7 @@ class HostCacheTest { settingsMock.ignore.getHostClearInterval { 0 } settingsMock.ignore.getHostHopelessInterval { 0 } settingsMock.ignore.getHostRejectInterval { 0 } + settingsMock.ignore.getHostHopelessPurgeInterval { 0 } initMocks() def rv = cache.getHosts(5)