Skip to content

Commit 2b93736

Browse files
committed
Used dependency injection in network threads
1 parent f2bb4d1 commit 2b93736

10 files changed

+64
-41
lines changed

src/bitmessageqt/settings.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ def accept(self):
414414
'bitmessagesettings', 'udp'):
415415
self.config.set('bitmessagesettings', 'udp', str(udp_enabled))
416416
if udp_enabled:
417-
announceThread = AnnounceThread()
417+
announceThread = AnnounceThread(self.config)
418418
announceThread.daemon = True
419419
announceThread.start()
420420
else:

src/network/__init__.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,19 @@ def start(config, state):
3838
readKnownNodes()
3939
connectionpool.pool.connectToStream(1)
4040
for thread in (
41-
BMNetworkThread(), InvThread(), AddrThread(),
42-
DownloadThread(), UploadThread()
41+
BMNetworkThread(queues), InvThread(protocol, state, queues, addresses),
42+
AddrThread(protocol, queues), DownloadThread(state, protocol, addresses),
43+
UploadThread(protocol, state)
4344
):
4445
thread.daemon = True
4546
thread.start()
4647

4748
# Optional components
4849
for i in range(config.getint('threads', 'receive')):
49-
thread = ReceiveQueueThread(i)
50+
thread = ReceiveQueueThread(queues, i)
5051
thread.daemon = True
5152
thread.start()
5253
if config.safeGetBoolean('bitmessagesettings', 'udp'):
53-
state.announceThread = AnnounceThread()
54+
state.announceThread = AnnounceThread(config)
5455
state.announceThread.daemon = True
5556
state.announceThread.start()

src/network/addrthread.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
# magic imports!
77
import connectionpool
88
from helper_random import randomshuffle
9-
from protocol import assembleAddrMessage
10-
from network import queues # FIXME: init with queue
119

1210
from threads import StoppableThread
1311

@@ -16,12 +14,17 @@ class AddrThread(StoppableThread):
1614
"""(Node) address broadcasting thread"""
1715
name = "AddrBroadcaster"
1816

17+
def __init__(self, protocol, queues):
18+
self.protocol = protocol
19+
self.queues = queues
20+
StoppableThread.__init__(self)
21+
1922
def run(self):
2023
while not self._stopped:
2124
chunk = []
2225
while True:
2326
try:
24-
data = queues.addrQueue.get(False)
27+
data = self.queues.addrQueue.get(False)
2528
chunk.append(data)
2629
except queue.Empty:
2730
break
@@ -41,9 +44,9 @@ def run(self):
4144
continue
4245
filtered.append((stream, peer, seen))
4346
if filtered:
44-
i.append_write_buf(assembleAddrMessage(filtered))
47+
i.append_write_buf(self.protocol.assembleAddrMessage(filtered))
4548

46-
queues.addrQueue.iterate()
49+
self.queues.addrQueue.iterate()
4750
for i in range(len(chunk)):
48-
queues.addrQueue.task_done()
51+
self.queues.addrQueue.task_done()
4952
self.stop.wait(1)

src/network/announcethread.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
# magic imports!
77
import connectionpool
8-
from network import config
98
from protocol import assembleAddrMessage
109

1110
from node import Peer
@@ -17,18 +16,22 @@ class AnnounceThread(StoppableThread):
1716
name = "Announcer"
1817
announceInterval = 60
1918

19+
def __init__(self, config):
20+
self.config = config
21+
StoppableThread.__init__(self)
22+
2023
def run(self):
2124
lastSelfAnnounced = 0
2225
while not self._stopped:
2326
processed = 0
2427
if lastSelfAnnounced < time.time() - self.announceInterval:
25-
self.announceSelf()
28+
self.announceSelf(self.config)
2629
lastSelfAnnounced = time.time()
2730
if processed == 0:
2831
self.stop.wait(10)
2932

3033
@staticmethod
31-
def announceSelf():
34+
def announceSelf(config):
3235
"""Announce our presence"""
3336
for connection in connectionpool.pool.udpSockets.values():
3437
if not connection.announcing:

src/network/downloadthread.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
`DownloadThread` class definition
33
"""
44
import time
5-
from network import state, protocol, addresses, dandelion_ins
5+
from network import dandelion_ins
66
import helper_random
77
import connectionpool
88
from objectracker import missingObjects
@@ -17,8 +17,11 @@ class DownloadThread(StoppableThread):
1717
cleanInterval = 60
1818
requestExpires = 3600
1919

20-
def __init__(self):
20+
def __init__(self, state, protocol, addresses):
2121
super(DownloadThread, self).__init__(name="Downloader")
22+
self.state = state
23+
self.protocol = protocol
24+
self.addresses = addresses
2225
self.lastCleaned = time.time()
2326

2427
def cleanPending(self):
@@ -57,7 +60,7 @@ def run(self):
5760
payload = bytearray()
5861
chunkCount = 0
5962
for chunk in request:
60-
if chunk in state.Inventory and not dandelion_ins.hasHash(chunk):
63+
if chunk in self.state.Inventory and not dandelion_ins.hasHash(chunk):
6164
try:
6265
del i.objectsNewToMe[chunk]
6366
except KeyError:
@@ -68,8 +71,8 @@ def run(self):
6871
missingObjects[chunk] = now
6972
if not chunkCount:
7073
continue
71-
payload[0:0] = addresses.encodeVarint(chunkCount)
72-
i.append_write_buf(protocol.CreatePacket('getdata', payload))
74+
payload[0:0] = self.addresses.encodeVarint(chunkCount)
75+
i.append_write_buf(self.protocol.CreatePacket('getdata', payload))
7376
self.logger.debug(
7477
'%s:%i Requesting %i objects',
7578
i.destination.host, i.destination.port, chunkCount)

src/network/invthread.py

+17-11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import random
66
from time import time
77

8-
from network import protocol, state, queues, addresses
98
import connectionpool
109
from network import dandelion_ins
1110
from threads import StoppableThread
@@ -34,6 +33,13 @@ class InvThread(StoppableThread):
3433

3534
name = "InvBroadcaster"
3635

36+
def __init__(self, protocol, state, queues, addresses):
37+
self.protocol = protocol
38+
self.state = state
39+
self.queues = queues
40+
self.addresses = addresses
41+
StoppableThread.__init__(self)
42+
3743
@staticmethod
3844
def handleLocallyGenerated(stream, hashId):
3945
"""Locally generated inventory items require special handling"""
@@ -45,13 +51,13 @@ def handleLocallyGenerated(stream, hashId):
4551
connection.objectsNewToThem[hashId] = time()
4652

4753
def run(self): # pylint: disable=too-many-branches
48-
while not state.shutdown: # pylint: disable=too-many-nested-blocks
54+
while not self.state.shutdown: # pylint: disable=too-many-nested-blocks
4955
chunk = []
5056
while True:
5157
# Dandelion fluff trigger by expiration
52-
handleExpiredDandelion(dandelion_ins.expire(queues.invQueue))
58+
handleExpiredDandelion(dandelion_ins.expire(self.queues.invQueue))
5359
try:
54-
data = queues.invQueue.get(False)
60+
data = self.queues.invQueue.get(False)
5561
chunk.append((data[0], data[1]))
5662
# locally generated
5763
if len(data) == 2 or data[2] is None:
@@ -78,7 +84,7 @@ def run(self): # pylint: disable=too-many-branches
7884
if random.randint(1, 100) >= dandelion_ins.enabled: # nosec B311
7985
fluffs.append(inv[1])
8086
# send a dinv only if the stem node supports dandelion
81-
elif connection.services & protocol.NODE_DANDELION > 0:
87+
elif connection.services & self.protocol.NODE_DANDELION > 0:
8288
stems.append(inv[1])
8389
else:
8490
fluffs.append(inv[1])
@@ -87,20 +93,20 @@ def run(self): # pylint: disable=too-many-branches
8793

8894
if fluffs:
8995
random.shuffle(fluffs)
90-
connection.append_write_buf(protocol.CreatePacket(
96+
connection.append_write_buf(self.protocol.CreatePacket(
9197
'inv',
92-
addresses.encodeVarint(
98+
self.addresses.encodeVarint(
9399
len(fluffs)) + ''.join(fluffs)))
94100
if stems:
95101
random.shuffle(stems)
96-
connection.append_write_buf(protocol.CreatePacket(
102+
connection.append_write_buf(self.protocol.CreatePacket(
97103
'dinv',
98-
addresses.encodeVarint(
104+
self.addresses.encodeVarint(
99105
len(stems)) + ''.join(stems)))
100106

101-
queues.invQueue.iterate()
107+
self.queues.invQueue.iterate()
102108
for _ in range(len(chunk)):
103-
queues.invQueue.task_done()
109+
self.queues.invQueue.task_done()
104110

105111
dandelion_ins.reRandomiseStems()
106112

src/network/networkthread.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,23 @@
33
"""
44
import network.asyncore_pollchoose as asyncore
55
import connectionpool
6-
from network import queues
76
from threads import StoppableThread
87

98

109
class BMNetworkThread(StoppableThread):
1110
"""Main network thread"""
1211
name = "Asyncore"
1312

13+
def __init__(self, queues):
14+
self.queues = queues
15+
StoppableThread.__init__(self)
16+
1417
def run(self):
1518
try:
1619
while not self._stopped:
1720
connectionpool.pool.loop()
1821
except Exception as e:
19-
queues.excQueue.put((self.name, e))
22+
self.queues.excQueue.put((self.name, e))
2023
raise
2124

2225
def stopThread(self):

src/network/receivequeuethread.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@
77

88
import connectionpool
99
from network.advanceddispatcher import UnknownStateError
10-
from network import queues
1110
from threads import StoppableThread
1211

1312

1413
class ReceiveQueueThread(StoppableThread):
1514
"""This thread processes data received from the network
1615
(which is done by the asyncore thread)"""
17-
def __init__(self, num=0):
16+
def __init__(self, queues, num=0):
17+
self.queues = queues
1818
super(ReceiveQueueThread, self).__init__(name="ReceiveQueue_%i" % num)
1919

2020
def run(self):
2121
while not self._stopped:
2222
try:
23-
dest = queues.receiveDataQueue.get(block=True, timeout=1)
23+
dest = self.queues.receiveDataQueue.get(block=True, timeout=1)
2424
except Queue.Empty:
2525
continue
2626

@@ -38,7 +38,7 @@ def run(self):
3838
connection = connectionpool.pool.getConnectionByAddr(dest)
3939
# connection object not found
4040
except KeyError:
41-
queues.receiveDataQueue.task_done()
41+
self.queues.receiveDataQueue.task_done()
4242
continue
4343
try:
4444
connection.process()
@@ -52,4 +52,4 @@ def run(self):
5252
self.logger.error('Socket error: %s', err)
5353
except: # noqa:E722
5454
self.logger.error('Error processing', exc_info=True)
55-
queues.receiveDataQueue.task_done()
55+
self.queues.receiveDataQueue.task_done()

src/network/uploadthread.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import time
55

66
import helper_random
7-
from network import protocol, state
87
import connectionpool
98
from randomtrackingdict import RandomTrackingDict
109
from network import dandelion_ins
@@ -18,6 +17,11 @@ class UploadThread(StoppableThread):
1817
maxBufSize = 2097152 # 2MB
1918
name = "Uploader"
2019

20+
def __init__(self, protocol, state):
21+
self.protocol = protocol
22+
self.state = state
23+
StoppableThread.__init__(self)
24+
2125
def run(self):
2226
while not self._stopped:
2327
uploaded = 0
@@ -48,8 +52,8 @@ def run(self):
4852
i.destination)
4953
break
5054
try:
51-
payload.extend(protocol.CreatePacket(
52-
'object', state.Inventory[chunk].payload))
55+
payload.extend(self.protocol.CreatePacket(
56+
'object', self.state.Inventory[chunk].payload))
5357
chunk_count += 1
5458
except KeyError:
5559
i.antiIntersectionDelay()

src/tests/test_network.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def test_udp(self):
7474

7575
for _ in range(10):
7676
try:
77-
self.state.announceThread.announceSelf()
77+
self.state.announceThread.announceSelf(self.config)
7878
except AttributeError:
7979
self.fail('state.announceThread is not set properly')
8080
time.sleep(1)

0 commit comments

Comments
 (0)