WIP: Added mock code #1883

Draft
kdcis wants to merge 10 commits from kdcis/mock-test into v0.6
14 changed files with 653 additions and 30 deletions

View File

@ -0,0 +1,52 @@
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
"""
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
Bitmessage mock
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
"""
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
from pybitmessage.class_addressGenerator import addressGenerator
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
from pybitmessage.class_singleWorker import singleWorker
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
from pybitmessage.class_objectProcessor import objectProcessor
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
from pybitmessage.inventory import Inventory
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
from pybitmessage.bmconfigparser import BMConfigParser
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# pylint: disable=too-few-public-methods,no-init,old-style-class
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
class MockMain:
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
"""Mock main function"""
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# pylint: disable=no-self-use
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
def start(self):
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
"""Start main application"""
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# pylint: disable=too-many-statements,too-many-branches,too-many-locals, unused-variable
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
config = BMConfigParser()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
daemon = config.safeGetBoolean('bitmessagesettings', 'daemon')
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# Start the address generation thread
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
addressGeneratorThread = addressGenerator()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# close the main program even if there are threads left
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
addressGeneratorThread.daemon = True
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
addressGeneratorThread.start()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# Start the thread that calculates POWs
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
singleWorkerThread = singleWorker()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# close the main program even if there are threads left
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
singleWorkerThread.daemon = True
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
singleWorkerThread.start()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# Start the thread that calculates POWs
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
objectProcessorThread = objectProcessor()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# DON'T close the main program even the thread remains.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# This thread checks the shutdown variable after processing
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
# each object.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
objectProcessorThread.daemon = False
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
objectProcessorThread.start()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
Inventory() # init
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
def main():
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
"""Triggers main module"""
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
mainprogram = MockMain()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
mainprogram.start()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
if __name__ == "__main__":
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.
main()
PeterSurda commented 2021-12-13 06:46:41 +01:00 (Migrated from github.com)
Review

here it can start launching the mock threads.

here it can start launching the mock threads.

View File

@ -1,14 +1,14 @@
"""Mock kivy app with mock threads.""" """Mock kivy app with mock threads."""
from pybitmessage import state from pybitmessage import state
from pybitmessage.bitmessagekivy.mpybit import NavigateApp from pybitmessage.mpybit import NavigateApp
from class_addressGenerator import FakeAddressGenerator from pybitmessage.class_addressGenerator import addressGenerator
def main(): def main():
"""main method for starting threads""" """main method for starting threads"""
# Start the address generation thread # Start the address generation thread
addressGeneratorThread = FakeAddressGenerator() addressGeneratorThread = addressGenerator()
# close the main program even if there are threads left # close the main program even if there are threads left
addressGeneratorThread.daemon = True addressGeneratorThread.daemon = True
addressGeneratorThread.start() addressGeneratorThread.start()

View File

View File

@ -0,0 +1,273 @@
"""
BMConfigParser class definition and default configuration settings
"""
import os
import shutil
import sys # FIXME: bad style! write more generally
from datetime import datetime
from six import string_types
from six.moves import configparser
try:
import state
from singleton import Singleton
except ImportError:
from pybitmessage import state
from pybitmessage.singleton import Singleton
SafeConfigParser = configparser.SafeConfigParser
BMConfigDefaults = {
"bitmessagesettings": {
"maxaddrperstreamsend": 500,
"maxbootstrapconnections": 20,
"maxdownloadrate": 0,
"maxoutboundconnections": 8,
"maxtotalconnections": 200,
"maxuploadrate": 0,
"apiinterface": "127.0.0.1",
"apiport": 8442,
"udp": "True"
},
"threads": {
"receive": 3,
},
"network": {
"bind": "",
"dandelion": 90,
},
"inventory": {
"storage": "sqlite",
"acceptmismatch": "False",
},
"knownnodes": {
"maxnodes": 20000,
},
"zlib": {
"maxsize": 1048576
}
}
@Singleton
class BMConfigParser(SafeConfigParser):
"""
Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
with additional methods specific to bitmessage config.
"""
# pylint: disable=too-many-ancestors
_temp = {}
def set(self, section, option, value=None):
if self._optcre is self.OPTCRE or value:
if not isinstance(value, string_types):
raise TypeError("option values must be strings")
if not self.validate(section, option, value):
raise ValueError("Invalid value %s" % value)
return SafeConfigParser.set(self, section, option, value)
# pylint: disable=redefined-builtinm, too-many-return-statements
def get(self, section, option, raw=False, vars=None):
if sys.version_info[0] == 3:
# pylint: disable=arguments-differ
try:
if section == "bitmessagesettings" and option == "timeformat":
return SafeConfigParser.get(
self, section, option, raw=True, vars=vars)
try:
return self._temp[section][option]
except KeyError:
pass
return SafeConfigParser.get(
self, section, option, raw=True, vars=vars)
except configparser.InterpolationError:
return SafeConfigParser.get(
self, section, option, raw=True, vars=vars)
except (configparser.NoSectionError, configparser.NoOptionError) as e:
try:
return BMConfigDefaults[section][option]
except (KeyError, ValueError, AttributeError):
raise e
else:
# pylint: disable=arguments-differ
try:
if section == "bitmessagesettings" and option == "timeformat":
return SafeConfigParser.get(
self, section, option, raw, vars)
try:
return self._temp[section][option]
except KeyError:
pass
return SafeConfigParser.get(
self, section, option, True, vars)
except configparser.InterpolationError:
return SafeConfigParser.get(
self, section, option, True, vars)
except (configparser.NoSectionError, configparser.NoOptionError) as e:
try:
return BMConfigDefaults[section][option]
except (KeyError, ValueError, AttributeError):
raise e
def setTemp(self, section, option, value=None):
"""Temporary set option to value, not saving."""
try:
self._temp[section][option] = value
except KeyError:
self._temp[section] = {option: value}
def safeGetBoolean(self, section, field):
"""Return value as boolean, False on exceptions"""
try:
# Used in the python2.7
# return self.getboolean(section, field)
# Used in the python3.5.2
# print(config, section, field)
return self.getboolean(section, field)
except (configparser.NoSectionError, configparser.NoOptionError,
ValueError, AttributeError):
return False
def safeGetInt(self, section, field, default=0):
"""Return value as integer, default on exceptions,
0 if default missing"""
try:
# Used in the python2.7
# return self.getint(section, field)
# Used in the python3.7.0
return int(self.get(section, field))
except (configparser.NoSectionError, configparser.NoOptionError,
ValueError, AttributeError):
return default
def safeGetFloat(self, section, field, default=0.0):
"""Return value as float, default on exceptions,
0.0 if default missing"""
try:
return self.getfloat(section, field)
except (configparser.NoSectionError, configparser.NoOptionError,
ValueError, AttributeError):
return default
def safeGet(self, section, option, default=None):
"""Return value as is, default on exceptions, None if default missing"""
try:
return self.get(section, option)
except (configparser.NoSectionError, configparser.NoOptionError,
ValueError, AttributeError):
return default
def items(self, section, raw=False, variables=None):
# pylint: disable=signature-differs
"""Return section variables as parent,
but override the "raw" argument to always True"""
return SafeConfigParser.items(self, section, True, variables)
def _reset(self):
"""Reset current config. There doesn't appear to be a built in
method for this"""
sections = self.sections()
for x in sections:
self.remove_section(x)
if sys.version_info[0] == 3:
@staticmethod
def addresses(hidden=False):
"""Return a list of local bitmessage addresses (from section labels)"""
return [x for x in BMConfigParser().sections() if x.startswith('BM-') and (
hidden or not BMConfigParser().safeGetBoolean(x, 'hidden'))]
def read(self, filenames):
self._reset()
SafeConfigParser.read(self, filenames)
for section in self.sections():
for option in self.options(section):
try:
# pylint: disable=unsubscriptable-object
if not self.validate(
section, option,
self[section][option]
):
try:
newVal = BMConfigDefaults[section][option]
except configparser.NoSectionError:
continue
except KeyError:
continue
SafeConfigParser.set(
self, section, option, newVal)
except configparser.InterpolationError:
continue
def readfp(self, fp, filename=None):
# pylint: disable=no-member
SafeConfigParser.read_file(self, fp)
else:
@staticmethod
def addresses():
"""Return a list of local bitmessage addresses (from section labels)"""
return [
x for x in BMConfigParser().sections() if x.startswith('BM-')]
def read(self, filenames):
"""Read config and populate defaults"""
self._reset()
SafeConfigParser.read(self, filenames)
for section in self.sections():
for option in self.options(section):
try:
if not self.validate(
section, option,
SafeConfigParser.get(self, section, option)
):
try:
newVal = BMConfigDefaults[section][option]
except KeyError:
continue
SafeConfigParser.set(
self, section, option, newVal)
except configparser.InterpolationError:
continue
def save(self):
"""Save the runtime config onto the filesystem"""
fileName = os.path.join(state.appdata, 'keys.dat')
fileNameBak = '.'.join([
fileName, datetime.now().strftime("%Y%j%H%M%S%f"), 'bak'])
# create a backup copy to prevent the accidental loss due to
# the disk write failure
try:
shutil.copyfile(fileName, fileNameBak)
# The backup succeeded.
fileNameExisted = True
except (IOError, Exception):
# The backup failed. This can happen if the file
# didn't exist before.
fileNameExisted = False
with open(fileName, 'w') as configfile:
self.write(configfile)
# delete the backup
if fileNameExisted:
os.remove(fileNameBak)
def validate(self, section, option, value):
"""Input validator interface (using factory pattern)"""
try:
return getattr(self, 'validate_%s_%s' % (section, option))(value)
except AttributeError:
return True
@staticmethod
def validate_bitmessagesettings_maxoutboundconnections(value):
"""Reject maxoutboundconnections that are too high or too low"""
try:
value = int(value)
except ValueError:
return False
if value < 0 or value > 8:
return False
return True

View File

@ -2,10 +2,6 @@
A thread for creating addresses A thread for creating addresses
""" """
import logging
import random
import threading
from six.moves import queue from six.moves import queue
from pybitmessage import state from pybitmessage import state
@ -13,7 +9,7 @@ from pybitmessage import queues
from pybitmessage.bmconfigparser import BMConfigParser from pybitmessage.bmconfigparser import BMConfigParser
# from network.threads import StoppableThread from pybitmessage.threads import StoppableThread
fake_addresses = { fake_addresses = {
@ -40,37 +36,18 @@ fake_addresses = {
} }
class StoppableThread(threading.Thread): class addressGenerator(StoppableThread):
"""Base class for application threads with stopThread method"""
name = None
logger = logging.getLogger('default')
def __init__(self, name=None):
if name:
self.name = name
super(StoppableThread, self).__init__(name=self.name)
self.stop = threading.Event()
self._stopped = False
random.seed()
self.logger.info('Init thread %s', self.name)
def stopThread(self):
"""Stop the thread"""
self._stopped = True
self.stop.set()
class FakeAddressGenerator(StoppableThread):
"""A thread for creating fake addresses""" """A thread for creating fake addresses"""
name = "addressGenerator" name = "addressGenerator"
address_list = list(fake_addresses.keys()) address_list = list(fake_addresses.keys())
def stopThread(self): def stopThread(self):
""""To stop address generator thread"""
try: try:
queues.addressGeneratorQueue.put(("stopThread", "data")) queues.addressGeneratorQueue.put(("stopThread", "data"))
except queue.Full: except queue.Full:
self.logger.warning('addressGeneratorQueue is Full') self.logger.warning('addressGeneratorQueue is Full')
super(FakeAddressGenerator, self).stopThread() super(addressGenerator, self).stopThread()
def run(self): def run(self):
""" """

View File

@ -0,0 +1,52 @@
"""
The objectProcessor thread, of which there is only one,
processes the network objects
"""
import logging
import random
import threading
import queues
import state
# from helper_sql import sql_ready, sqlExecute, sqlQuery
# from network import bmproto
logger = logging.getLogger('default')
class objectProcessor(threading.Thread):
"""
The objectProcessor thread, of which there is only one, receives network
objects (msg, broadcast, pubkey, getpubkey) from the receiveDataThreads.
"""
def __init__(self):
threading.Thread.__init__(self, name="objectProcessor")
random.seed()
# It may be the case that the last time Bitmessage was running,
# the user closed it before it finished processing everything in the
# objectProcessorQueue. Assuming that Bitmessage wasn't closed
# forcefully, it should have saved the data in the queue into the
# objectprocessorqueue table. Let's pull it out.
# sql_ready.wait()
# queryreturn = sqlQuery(
# 'SELECT objecttype, data FROM objectprocessorqueue')
# for objectType, data in queryreturn:
# queues.objectProcessorQueue.put((objectType, data))
# sqlExecute('DELETE FROM objectprocessorqueue')
# logger.debug(
# 'Loaded %s objects from disk into the objectProcessorQueue.',
# len(queryreturn))
# self._ack_obj = bmproto.BMStringParser()
self.successfullyDecryptMessageTimings = []
def run(self):
"""Process the objects from `.queues.objectProcessorQueue`"""
while True:
# pylint: disable=unused-variable
objectType, data = queues.objectProcessorQueue.get()
if state.shutdown:
state.shutdown = 2
break

View File

@ -0,0 +1,44 @@
"""
Thread for performing PoW
"""
from __future__ import division
from six.moves import queue
from pybitmessage import state
from pybitmessage import queues
from pybitmessage.threads import StoppableThread
class singleWorker(StoppableThread):
"""Thread for performing PoW"""
def __init__(self):
super(singleWorker, self).__init__(name="singleWorker")
self.busy = None
def stopThread(self):
"""Signal through the queue that the thread should be stopped"""
try:
queues.workerQueue.put(("stopThread", "data"))
except queue.Full:
self.logger.error('workerQueue is Full')
super(singleWorker, self).stopThread()
def run(self):
"""To run single worker thread"""
if state.shutdown > 0:
return
while state.shutdown == 0:
self.busy = 0
command, _ = queues.workerQueue.get()
self.busy = 1
if command == 'stopThread':
self.busy = 0
return
queues.workerQueue.task_done()
self.logger.info("Quitting...")

View File

@ -0,0 +1,15 @@
"""The Inventory singleton"""
# TODO make this dynamic, and watch out for frozen, like with messagetypes
from singleton import Singleton
# pylint: disable=old-style-class,too-few-public-methods
@Singleton
class Inventory():
"""
Inventory singleton class which uses storage backends
to manage the inventory.
"""
def __init__(self):
self.numberOfInventoryLookupsPerformed = 0

View File

@ -0,0 +1,28 @@
"""
Dummy implementation for kivy Desktop and android(mobile) interface
"""
# pylint: disable=too-few-public-methods
from kivy.app import App
from kivy.uix.label import Label
class NavigateApp(App):
"""Navigation Layout of class"""
def build(self):
"""Method builds the widget"""
# pylint: disable=no-self-use
return Label(text="Hello World !")
def clickNavDrawer(self):
"""method for clicking navigation drawer"""
pass
def addingtoaddressbook(self):
"""method for clicking address book popup"""
pass
if __name__ == '__main__':
NavigateApp().run()

View File

@ -0,0 +1,55 @@
"""Most of the queues used by bitmessage threads are defined here."""
import threading
import time
from six.moves import queue
# try:
# from multiqueue import MultiQueue
# except ImportError:
# from .multiqueue import MultiQueue
class ObjectProcessorQueue(queue.Queue):
"""Special queue class using lock for `.threads.objectProcessor`"""
maxSize = 32000000
def __init__(self):
queue.Queue.__init__(self)
self.sizeLock = threading.Lock()
#: in Bytes. We maintain this to prevent nodes from flooding us
#: with objects which take up too much memory. If this gets
#: too big we'll sleep before asking for further objects.
self.curSize = 0
def put(self, item, block=True, timeout=None):
while self.curSize >= self.maxSize:
time.sleep(1)
with self.sizeLock:
self.curSize += len(item[1])
queue.Queue.put(self, item, block, timeout)
def get(self, block=True, timeout=None):
item = queue.Queue.get(self, block, timeout)
with self.sizeLock:
self.curSize -= len(item[1])
return item
workerQueue = queue.Queue()
UISignalQueue = queue.Queue()
addressGeneratorQueue = queue.Queue()
#: `.network.ReceiveQueueThread` instances dump objects they hear
#: on the network into this queue to be processed.
objectProcessorQueue = ObjectProcessorQueue()
# invQueue = MultiQueue()
# addrQueue = MultiQueue()
portCheckerQueue = queue.Queue()
receiveDataQueue = queue.Queue()
#: The address generator thread uses this queue to get information back
#: to the API thread.
apiAddressGeneratorReturnQueue = queue.Queue()
#: for exceptions
excQueue = queue.Queue()

View File

@ -0,0 +1,22 @@
"""
Singleton decorator definition
"""
from functools import wraps
def Singleton(cls):
"""
Decorator implementing the singleton pattern:
it restricts the instantiation of a class to one "single" instance.
"""
instances = {}
# https://github.com/sphinx-doc/sphinx/issues/3783
@wraps(cls)
def getinstance():
"""Find an instance or save newly created one"""
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance

View File

@ -0,0 +1,72 @@
"""
Global runtime variables.
"""
neededPubkeys = {}
streamsInWhichIAmParticipating = []
extPort = None
"""For UPnP"""
socksIP = None
"""for Tor hidden service"""
appdata = ''
"""holds the location of the application data storage directory"""
shutdown = 0
"""
Set to 1 by the `.shutdown.doCleanShutdown` function.
Used to tell the threads to exit.
"""
# Component control flags - set on startup, do not change during runtime
# The defaults are for standalone GUI (default operating mode)
enableNetwork = True
"""enable network threads"""
enableObjProc = True
"""enable object processing thread"""
enableAPI = True
"""enable API (if configured)"""
enableGUI = True
"""enable GUI (QT or ncurses)"""
enableSTDIO = False
"""enable STDIO threads"""
enableKivy = False
"""enable kivy app and test cases"""
curses = False
maximumNumberOfHalfOpenConnections = 0
maximumLengthOfTimeToBotherResendingMessages = 0
invThread = None
addrThread = None
downloadThread = None
uploadThread = None
ownAddresses = {}
discoveredPeers = {}
dandelion = 0
testmode = False
clientHasReceivedIncomingConnections = False
"""used by API command clientStatus"""
numberOfMessagesProcessed = 0
numberOfBroadcastsProcessed = 0
numberOfPubkeysProcessed = 0
statusIconColor = 'red'
"""
GUI status icon color
.. note:: bad style, refactor it
"""
ackdataForWhichImWatching = {}
thisapp = None
"""Singleton instance"""

View File

@ -0,0 +1,33 @@
"""Threading primitives for the network package"""
import logging
import random
import threading
class StoppableThread(threading.Thread):
"""Base class for application threads with stopThread method"""
name = None
logger = logging.getLogger('default')
def __init__(self, name=None):
if name:
self.name = name
super(StoppableThread, self).__init__(name=self.name)
self.stop = threading.Event()
self._stopped = False
random.seed()
self.logger.info('Init thread %s', self.name)
def stopThread(self):
"""Stop the thread"""
self._stopped = True
self.stop.set()
class BusyError(threading.ThreadError):
"""
Thread error raised when another connection holds the lock
we are trying to acquire.
"""
pass