wip on HostPool and test
This commit is contained in:
@@ -4,4 +4,15 @@ class Host {
|
||||
|
||||
def destination
|
||||
def verifyTime
|
||||
boolean leafSlots
|
||||
boolean peerSlots
|
||||
int verificationFailures
|
||||
|
||||
public int hashCode() {
|
||||
return destination.hashCode()
|
||||
}
|
||||
|
||||
public boolean equals(other) {
|
||||
return destination.equals(other.destination)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,10 @@ public class HostCache {
|
||||
|
||||
payload = dissector.getPayload()
|
||||
payload = json.parse(payload)
|
||||
if (payload.type == null) {
|
||||
println "WARN: type field missing"
|
||||
return
|
||||
}
|
||||
switch(payload.type) {
|
||||
case "Ping" :
|
||||
println "Ping"
|
||||
|
||||
@@ -1,20 +1,72 @@
|
||||
package com.muwire.hostcache
|
||||
|
||||
import java.util.stream.Collectors
|
||||
|
||||
class HostPool {
|
||||
|
||||
final def maxFailures
|
||||
final def maxAge
|
||||
|
||||
def verified = new HashSet()
|
||||
|
||||
synchronized def getVerified(int max) {
|
||||
def asList = verified.asList()
|
||||
def unverified = new HashSet()
|
||||
|
||||
HostPool(maxFailures, maxAge) {
|
||||
this.maxAge = maxAge
|
||||
this.maxFailures = maxFailures
|
||||
}
|
||||
|
||||
synchronized def getVerified(int max, boolean leaf) {
|
||||
if (verified.isEmpty()) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
def asList = verified.stream().filter({ it -> leaf ? it.leafSlots : it.peerSlots}).collect(Collectors.toList())
|
||||
Collections.shuffle(asList)
|
||||
return asList[0..max].collect { it -> it.destination }
|
||||
|
||||
return asList[0..Math.min(max, asList.size()) -1]
|
||||
}
|
||||
|
||||
synchronized def addUnverified(host) {
|
||||
|
||||
unverified.add(host)
|
||||
}
|
||||
|
||||
synchronized def getUnverified(int max) {
|
||||
if (unverified.isEmpty()) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
def asList = unverified.asList()
|
||||
Collections.shuffle(asList)
|
||||
return asList[0..(Math.min(max, asList.size())-1)]
|
||||
}
|
||||
|
||||
synchronized def verify(host) {
|
||||
if (!unverified.remove(host))
|
||||
throw new IllegalArgumentException()
|
||||
host.verifyTime = System.currentTimeMillis();
|
||||
host.verificationFailures = 0
|
||||
verified.add(host)
|
||||
}
|
||||
|
||||
synchronized def fail(host) {
|
||||
if (!unverified.contains(host))
|
||||
throw new IllegalArgumentException()
|
||||
host.verificationFailures++
|
||||
}
|
||||
|
||||
synchronized def age() {
|
||||
final long now = System.currentTimeMillis()
|
||||
for (Iterator iter = verified.iterator(); iter.hasNext();) {
|
||||
def host = iter.next()
|
||||
if (host.verifyTime + maxAge < now) {
|
||||
iter.remove()
|
||||
unverified.add(host)
|
||||
}
|
||||
}
|
||||
|
||||
for (Iterator iter = unverified.iterator(); iter.hasNext();) {
|
||||
def host = iter.next()
|
||||
if (host.verificationFailures >= maxFailures) {
|
||||
iter.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,163 @@
|
||||
package com.muwire.hostcache
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.*
|
||||
|
||||
class HostPoolTest {
|
||||
|
||||
@Test
|
||||
def testGetVerified() {
|
||||
def hp
|
||||
Host freeLeafs, freePeers, freeBoth, freeNone
|
||||
|
||||
@Before
|
||||
void before() {
|
||||
hp = new HostPool(3, 10)
|
||||
|
||||
freeLeafs = new Host()
|
||||
freeLeafs.destination = "freeLeafs"
|
||||
freeLeafs.leafSlots = true
|
||||
|
||||
freePeers = new Host()
|
||||
freePeers.destination = "freePeers"
|
||||
freePeers.peerSlots = true
|
||||
|
||||
freeBoth = new Host()
|
||||
freeBoth.destination = "freeBoth"
|
||||
freeBoth.leafSlots = true
|
||||
freeBoth.peerSlots = true
|
||||
|
||||
freeNone = new Host()
|
||||
freeNone.destination = "freeNone"
|
||||
}
|
||||
|
||||
def addAllUnverified() {
|
||||
hp.addUnverified(freeLeafs)
|
||||
hp.addUnverified(freePeers)
|
||||
hp.addUnverified(freeBoth)
|
||||
hp.addUnverified(freeNone)
|
||||
}
|
||||
|
||||
def verifyAll() {
|
||||
hp.verify(freeBoth)
|
||||
hp.verify(freeLeafs)
|
||||
hp.verify(freePeers)
|
||||
hp.verify(freeNone)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoVerified() {
|
||||
assert hp.getVerified(1, true).isEmpty()
|
||||
assert hp.getVerified(1, false).isEmpty()
|
||||
|
||||
addAllUnverified()
|
||||
|
||||
assert hp.getVerified(1, true).isEmpty()
|
||||
assert hp.getVerified(1, false).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOneVerified() {
|
||||
addAllUnverified()
|
||||
hp.verify(freeBoth)
|
||||
|
||||
assert hp.getVerified(10, true).contains(freeBoth)
|
||||
assert hp.getVerified(10, false).contains(freeBoth)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilterByType() {
|
||||
addAllUnverified()
|
||||
verifyAll()
|
||||
def verifiedLeafSlots = hp.getVerified(10, true)
|
||||
assert verifiedLeafSlots.size() == 2
|
||||
assert verifiedLeafSlots.contains(freeBoth)
|
||||
assert verifiedLeafSlots.contains(freeLeafs)
|
||||
|
||||
def verifiedPeerSlots = hp.getVerified(10, false)
|
||||
assert verifiedPeerSlots.size() == 2
|
||||
assert verifiedPeerSlots.contains(freeBoth)
|
||||
assert verifiedPeerSlots.contains(freePeers)
|
||||
}
|
||||
|
||||
@Test
|
||||
void getFewerThanAvailable() {
|
||||
addAllUnverified()
|
||||
verifyAll()
|
||||
def verifiedLeafSlots = hp.getVerified(1, true)
|
||||
assert verifiedLeafSlots.size() == 1
|
||||
assert verifiedLeafSlots.contains(freeBoth) || verifiedLeafSlots.contains(freeLeafs)
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUnverified() {
|
||||
assert hp.getUnverified().isEmpty()
|
||||
|
||||
addAllUnverified()
|
||||
|
||||
def allUnverified = hp.getUnverified(10)
|
||||
assert allUnverified.size() == 4
|
||||
assert allUnverified.contains(freeLeafs)
|
||||
assert allUnverified.contains(freePeers)
|
||||
assert allUnverified.contains(freeBoth)
|
||||
assert allUnverified.contains(freeNone)
|
||||
|
||||
def twoUnverified = hp.getUnverified(2)
|
||||
assert twoUnverified.size() == 2
|
||||
|
||||
def oneUnverified = hp.getUnverified(1)
|
||||
assert oneUnverified.size() == 1
|
||||
assert oneUnverified.contains(freeLeafs) || oneUnverified.contains(freePeers) ||
|
||||
oneUnverified.contains(freeBoth) || oneUnverified.contains(freeNone)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailHost() {
|
||||
hp.addUnverified(freeBoth)
|
||||
assert hp.getUnverified(10).size() == 1
|
||||
|
||||
hp.fail(freeBoth)
|
||||
hp.age()
|
||||
assert hp.getUnverified(10).size() == 1
|
||||
|
||||
hp.fail(freeBoth)
|
||||
hp.age()
|
||||
assert hp.getUnverified(10).size() == 1
|
||||
|
||||
hp.fail(freeBoth)
|
||||
hp.age()
|
||||
assert hp.getUnverified(10).isEmpty()
|
||||
assert hp.getVerified(10, true).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifyResetsFailures() {
|
||||
hp.addUnverified(freeBoth)
|
||||
assert hp.getUnverified(10).size() == 1
|
||||
|
||||
hp.fail(freeBoth)
|
||||
hp.age()
|
||||
assert hp.getUnverified(10).size() == 1
|
||||
|
||||
hp.fail(freeBoth)
|
||||
hp.age()
|
||||
assert hp.getUnverified(10).size() == 1
|
||||
|
||||
hp.verify(freeBoth)
|
||||
hp.age()
|
||||
assert hp.getUnverified(10).isEmpty()
|
||||
assert hp.getVerified(10, true).size() == 1
|
||||
}
|
||||
|
||||
@Test
|
||||
void ageHost() {
|
||||
hp.addUnverified(freeBoth)
|
||||
hp.verify(freeBoth)
|
||||
|
||||
hp.age()
|
||||
assert hp.getVerified(10,true).size() == 1
|
||||
assert hp.getUnverified(10).isEmpty()
|
||||
|
||||
Thread.sleep(20)
|
||||
hp.age()
|
||||
assert hp.getVerified(10,true).isEmpty()
|
||||
assert hp.getUnverified(10).size() == 1
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user