Merge branch '1214' into v0.6

This commit is contained in:
Peter Šurda 2018-04-11 13:19:53 +02:00
commit 4507464c56
Signed by untrusted user: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
5 changed files with 91 additions and 65 deletions

View File

@ -218,10 +218,12 @@ class Main:
sys.exit() sys.exit()
elif opt in ("-d", "--daemon"): elif opt in ("-d", "--daemon"):
daemon = True daemon = True
state.enableGUI = False # run without a UI
elif opt in ("-c", "--curses"): elif opt in ("-c", "--curses"):
state.curses = True state.curses = True
elif opt in ("-t", "--test"): elif opt in ("-t", "--test"):
state.testmode = daemon = True state.testmode = daemon = True
state.enableGUI = False # run without a UI
# is the application already running? If yes then exit. # is the application already running? If yes then exit.
shared.thisapp = singleinstance("", daemon) shared.thisapp = singleinstance("", daemon)
@ -241,15 +243,19 @@ class Main:
state.dandelion = 0 state.dandelion = 0
helper_bootstrap.knownNodes() helper_bootstrap.knownNodes()
# Start the address generation thread
addressGeneratorThread = addressGenerator()
addressGeneratorThread.daemon = True # close the main program even if there are threads left
addressGeneratorThread.start()
# Start the thread that calculates POWs # Not needed if objproc is disabled
singleWorkerThread = singleWorker() if state.enableObjProc:
singleWorkerThread.daemon = True # close the main program even if there are threads left
singleWorkerThread.start() # Start the address generation thread
addressGeneratorThread = addressGenerator()
addressGeneratorThread.daemon = True # close the main program even if there are threads left
addressGeneratorThread.start()
# Start the thread that calculates POWs
singleWorkerThread = singleWorker()
singleWorkerThread.daemon = True # close the main program even if there are threads left
singleWorkerThread.start()
# Start the SQL thread # Start the SQL thread
sqlLookup = sqlThread() sqlLookup = sqlThread()
@ -259,73 +265,84 @@ class Main:
Inventory() # init Inventory() # init
Dandelion() # init, needs to be early because other thread may access it early Dandelion() # init, needs to be early because other thread may access it early
# SMTP delivery thread # Enable object processor and SMTP only if objproc enabled
if daemon and BMConfigParser().safeGet("bitmessagesettings", "smtpdeliver", '') != '': if state.enableObjProc:
smtpDeliveryThread = smtpDeliver()
smtpDeliveryThread.start()
# SMTP daemon thread # SMTP delivery thread
if daemon and BMConfigParser().safeGetBoolean("bitmessagesettings", "smtpd"): if daemon and BMConfigParser().safeGet("bitmessagesettings", "smtpdeliver", '') != '':
smtpServerThread = smtpServer() smtpDeliveryThread = smtpDeliver()
smtpServerThread.start() smtpDeliveryThread.start()
# Start the thread that calculates POWs # SMTP daemon thread
objectProcessorThread = objectProcessor() if daemon and BMConfigParser().safeGetBoolean("bitmessagesettings", "smtpd"):
objectProcessorThread.daemon = False # DON'T close the main program even the thread remains. This thread checks the shutdown variable after processing each object. smtpServerThread = smtpServer()
objectProcessorThread.start() smtpServerThread.start()
# Start the thread that calculates POWs
objectProcessorThread = objectProcessor()
objectProcessorThread.daemon = False # DON'T close the main program even the thread remains. This thread checks the shutdown variable after processing each object.
objectProcessorThread.start()
# Start the cleanerThread # Start the cleanerThread
singleCleanerThread = singleCleaner() singleCleanerThread = singleCleaner()
singleCleanerThread.daemon = True # close the main program even if there are threads left singleCleanerThread.daemon = True # close the main program even if there are threads left
singleCleanerThread.start() singleCleanerThread.start()
shared.reloadMyAddressHashes() # Not needed if objproc disabled
shared.reloadBroadcastSendersForWhichImWatching() if state.enableObjProc:
shared.reloadMyAddressHashes()
shared.reloadBroadcastSendersForWhichImWatching()
if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'): # API is also objproc dependent
try: if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
apiNotifyPath = BMConfigParser().get( try:
'bitmessagesettings', 'apinotifypath') apiNotifyPath = BMConfigParser().get(
except: 'bitmessagesettings', 'apinotifypath')
apiNotifyPath = '' except:
if apiNotifyPath != '': apiNotifyPath = ''
with shared.printLock: if apiNotifyPath != '':
print('Trying to call', apiNotifyPath) with shared.printLock:
print('Trying to call', apiNotifyPath)
call([apiNotifyPath, "startingUp"]) call([apiNotifyPath, "startingUp"])
singleAPIThread = singleAPI() singleAPIThread = singleAPI()
singleAPIThread.daemon = True # close the main program even if there are threads left singleAPIThread.daemon = True # close the main program even if there are threads left
singleAPIThread.start() singleAPIThread.start()
BMConnectionPool() # start network components if networking is enabled
asyncoreThread = BMNetworkThread() if state.enableNetwork:
asyncoreThread.daemon = True BMConnectionPool()
asyncoreThread.start() asyncoreThread = BMNetworkThread()
for i in range(BMConfigParser().getint("threads", "receive")): asyncoreThread.daemon = True
receiveQueueThread = ReceiveQueueThread(i) asyncoreThread.start()
receiveQueueThread.daemon = True for i in range(BMConfigParser().getint("threads", "receive")):
receiveQueueThread.start() receiveQueueThread = ReceiveQueueThread(i)
announceThread = AnnounceThread() receiveQueueThread.daemon = True
announceThread.daemon = True receiveQueueThread.start()
announceThread.start() announceThread = AnnounceThread()
state.invThread = InvThread() announceThread.daemon = True
state.invThread.daemon = True announceThread.start()
state.invThread.start() state.invThread = InvThread()
state.addrThread = AddrThread() state.invThread.daemon = True
state.addrThread.daemon = True state.invThread.start()
state.addrThread.start() state.addrThread = AddrThread()
state.downloadThread = DownloadThread() state.addrThread.daemon = True
state.downloadThread.daemon = True state.addrThread.start()
state.downloadThread.start() state.downloadThread = DownloadThread()
state.downloadThread.daemon = True
state.downloadThread.start()
connectToStream(1) connectToStream(1)
if BMConfigParser().safeGetBoolean('bitmessagesettings','upnp'): if BMConfigParser().safeGetBoolean('bitmessagesettings','upnp'):
import upnp import upnp
upnpThread = upnp.uPnPThread() upnpThread = upnp.uPnPThread()
upnpThread.start() upnpThread.start()
else:
# Populate with hardcoded value (same as connectToStream above)
state.streamsInWhichIAmParticipating.append(1)
if daemon == False and BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon') == False: if daemon == False or state.enableGUI: # FIXME redundant?
if state.curses == False: if state.curses == False:
if not depends.check_pyqt(): if not depends.check_pyqt():
sys.exit( sys.exit(

View File

@ -65,7 +65,7 @@ class singleCleaner(threading.Thread, StoppableThread):
# If we are running as a daemon then we are going to fill up the UI # If we are running as a daemon then we are going to fill up the UI
# queue which will never be handled by a UI. We should clear it to # queue which will never be handled by a UI. We should clear it to
# save memory. # save memory.
if shared.thisapp.daemon: if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant?
queues.UISignalQueue.queue.clear() queues.UISignalQueue.queue.clear()
if timeWeLastClearedInventoryAndPubkeysTables < int(time.time()) - 7380: if timeWeLastClearedInventoryAndPubkeysTables < int(time.time()) - 7380:
timeWeLastClearedInventoryAndPubkeysTables = int(time.time()) timeWeLastClearedInventoryAndPubkeysTables = int(time.time())
@ -120,7 +120,7 @@ class singleCleaner(threading.Thread, StoppableThread):
if "Errno 28" in str(err): if "Errno 28" in str(err):
logger.fatal('(while receiveDataThread knownnodes.needToWriteKnownNodesToDisk) Alert: Your disk or data storage volume is full. ') logger.fatal('(while receiveDataThread knownnodes.needToWriteKnownNodesToDisk) Alert: Your disk or data storage volume is full. ')
queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True))) queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True)))
if shared.thisapp.daemon: if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant?
os._exit(0) os._exit(0)
shared.needToWriteKnownNodesToDisk = False shared.needToWriteKnownNodesToDisk = False

View File

@ -12,6 +12,7 @@ import threading
import traceback import traceback
import shared import shared
import state
from debug import logger from debug import logger
import queues import queues
import shutdown import shutdown
@ -66,7 +67,7 @@ def signal_handler(signal, frame):
"PyBitmessage", "MainThread"): "PyBitmessage", "MainThread"):
return return
logger.error("Got signal %i", signal) logger.error("Got signal %i", signal)
if shared.thisapp.daemon: if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant?
shutdown.doCleanShutdown() shutdown.doCleanShutdown()
else: else:
allThreadTraceback(frame) allThreadTraceback(frame)

View File

@ -61,7 +61,7 @@ def doCleanShutdown():
except Queue.Empty: except Queue.Empty:
break break
if shared.thisapp.daemon: if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant?
logger.info('Clean shutdown complete.') logger.info('Clean shutdown complete.')
shared.thisapp.cleanup() shared.thisapp.cleanup()
os._exit(0) os._exit(0)

View File

@ -17,6 +17,14 @@ appdata = '' #holds the location of the application data storage directory
shutdown = 0 #Set to 1 by the doCleanShutdown function. Used to tell the proof of work worker threads to exit. shutdown = 0 #Set to 1 by the doCleanShutdown function. Used to tell the proof of work worker 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 threads
enableAPI = True # enable API (if configured)
enableGUI = True # enable GUI (QT or ncurses)
enableSTDIO = False # enable STDIO threads
curses = False curses = False
sqlReady = False # set to true by sqlTread when ready for processing sqlReady = False # set to true by sqlTread when ready for processing