Change peer discovery tracking from queue to a dict

- with a queue, a situation could occur when new entries are appended
but nothing is polling the queue
This commit is contained in:
Peter Šurda 2017-08-06 21:29:54 +02:00
parent 4564d37f5b
commit f338c00f8e
Signed by untrusted user: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
5 changed files with 40 additions and 25 deletions

View File

@ -38,6 +38,7 @@ resends msg messages in 5 days (then 10 days, then 20 days, etc...)
class singleCleaner(threading.Thread, StoppableThread):
cycleLength = 300
expireDiscoveredPeers = 300
def __init__(self):
threading.Thread.__init__(self, name="singleCleaner")
@ -126,6 +127,14 @@ class singleCleaner(threading.Thread, StoppableThread):
for connection in BMConnectionPool().inboundConnections.values() + BMConnectionPool().outboundConnections.values():
connection.clean()
# discovery tracking
exp = time.time() - singleCleander.expireDiscoveredPeers
reaper = (k for k, v in state.discoveredPeers.items() if v < exp)
for k in reaper:
try:
del state.discoveredPeers[k]
except KeyError:
pass
# TODO: cleanup pending upload / download
if state.shutdown == 0:

View File

@ -3,9 +3,15 @@ import random
from bmconfigparser import BMConfigParser
import knownnodes
from queues import portCheckerQueue, peerDiscoveryQueue
from queues import portCheckerQueue
import state
def getDiscoveredPeer(stream):
try:
peer = random.choice(state.discoveredPeers.keys())
except (IndexError, KeyError):
raise ValueError
def chooseConnection(stream):
haveOnion = BMConfigParser().safeGet("bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS'
if state.trustedPeer:
@ -13,26 +19,25 @@ def chooseConnection(stream):
try:
retval = portCheckerQueue.get(False)
portCheckerQueue.task_done()
return retval
except Queue.Empty:
pass
if random.choice((False, True)):
return getDiscoveredPeer(stream)
for i in range(50):
peer = random.choice(knownnodes.knownNodes[stream].keys())
try:
retval = peerDiscoveryQueue.get(False)
peerDiscoveryQueue.task_done()
except Queue.Empty:
for i in range(50):
peer = random.choice(knownnodes.knownNodes[stream].keys())
try:
rating = knownnodes.knownNodes[stream][peer]["rating"]
except TypeError:
print "Error in %s" % (peer)
rating = 0
if haveOnion and peer.host.endswith('.onion') and rating > 0:
rating *= 10
if rating > 1:
rating = 1
try:
if 0.05/(1.0-rating) > random.random():
return peer
except ZeroDivisionError:
return peer
raise ValueError
return retval
rating = knownnodes.knownNodes[stream][peer]["rating"]
except TypeError:
print "Error in %s" % (peer)
rating = 0
if haveOnion and peer.host.endswith('.onion') and rating > 0:
rating *= 10
if rating > 1:
rating = 1
try:
if 0.05/(1.0-rating) > random.random():
return peer
except ZeroDivisionError:
return peer
raise ValueError

View File

@ -9,7 +9,7 @@ from network.bmobject import BMObject, BMObjectInsufficientPOWError, BMObjectInv
import network.asyncore_pollchoose as asyncore
from network.objectracker import ObjectTracker
from queues import objectProcessorQueue, peerDiscoveryQueue, UISignalQueue, receiveDataQueue
from queues import objectProcessorQueue, UISignalQueue, receiveDataQueue
import state
import protocol
@ -100,7 +100,7 @@ class UDPSocket(BMProto):
return True
logger.debug("received peer discovery from %s:%i (port %i):", self.destination.host, self.destination.port, remoteport)
if self.local:
peerDiscoveryQueue.put(state.Peer(self.destination.host, remoteport))
state.discoveredPeers[state.Peer(self.destination.host, remoteport)] = time.time
return True
def bm_command_portcheck(self):

View File

@ -11,7 +11,6 @@ objectProcessorQueue = ObjectProcessorQueue()
invQueue = MultiQueue()
addrQueue = MultiQueue()
portCheckerQueue = Queue.Queue()
peerDiscoveryQueue = Queue.Queue()
receiveDataQueue = Queue.Queue()
apiAddressGeneratorReturnQueue = Queue.Queue(
) # The address generator thread uses this queue to get information back to the API thread.

View File

@ -41,6 +41,8 @@ ownAddresses = {}
# security.
trustedPeer = None
discoveredPeers = {}
Peer = collections.namedtuple('Peer', ['host', 'port'])
def resetNetworkProtocolAvailability():