GUI shutdown improvements
- it shows that it needs to wait for PoW to finish - it waits a bit for new objects to be distributed - it displays a better progress indicator in the status bar Previously, people who don't understand how PyBitmessage works sometimes shut it down immediately after they wrote a message. This would have caused the message to be stuck in the queue locally and not sent. Now, it will indicate that the PoW still needs to work, and it will wait a bit longer so that the message can spread. It's not a completely correct approach, because it does not know whether the message was really retrieved after the "inv" notification was sent.
This commit is contained in:
parent
167da731d0
commit
3dbb4d5ce9
|
@ -67,6 +67,8 @@ from utils import *
|
|||
from collections import OrderedDict
|
||||
from account import *
|
||||
from dialogs import AddAddressDialog
|
||||
from class_objectHashHolder import objectHashHolder
|
||||
from class_singleWorker import singleWorker
|
||||
|
||||
def _translate(context, text):
|
||||
return QtGui.QApplication.translate(context, text)
|
||||
|
@ -2644,7 +2646,64 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if reply is QtGui.QMessageBox.No:
|
||||
return
|
||||
'''
|
||||
|
||||
self.statusBar().showMessage(_translate(
|
||||
"MainWindow", "Shutting down PyBitmessage... %1%%").arg(str(0)))
|
||||
|
||||
# check if PoW queue empty
|
||||
maxWorkerQueue = 0
|
||||
curWorkerQueue = 1
|
||||
while curWorkerQueue > 0:
|
||||
# worker queue size
|
||||
curWorkerQueue = shared.workerQueue.qsize()
|
||||
# if worker is busy add 1
|
||||
for thread in threading.enumerate():
|
||||
try:
|
||||
if isinstance(thread, singleWorker):
|
||||
curWorkerQueue += thread.busy
|
||||
except:
|
||||
pass
|
||||
if curWorkerQueue > maxWorkerQueue:
|
||||
maxWorkerQueue = curWorkerQueue
|
||||
if curWorkerQueue > 0:
|
||||
self.statusBar().showMessage(_translate("MainWindow", "Waiting for PoW to finish... %1%").arg(str(50 * (maxWorkerQueue - curWorkerQueue) / maxWorkerQueue)))
|
||||
time.sleep(0.5)
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
|
||||
self.statusBar().showMessage(_translate("MainWindow", "Shutting down Pybitmessage... %1%").arg(str(50)))
|
||||
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
if maxWorkerQueue > 0:
|
||||
time.sleep(0.5) # a bit of time so that the hashHolder is populated
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
|
||||
# check if objectHashHolder empty
|
||||
self.statusBar().showMessage(_translate("MainWindow", "Waiting for objects to be sent... %1%").arg(str(50)))
|
||||
maxWaitingObjects = 0
|
||||
curWaitingObjects = 1
|
||||
while curWaitingObjects > 0:
|
||||
curWaitingObjects = 0
|
||||
for thread in threading.enumerate():
|
||||
try:
|
||||
if isinstance(thread, objectHashHolder):
|
||||
curWaitingObjects += thread.hashCount()
|
||||
except:
|
||||
pass
|
||||
if curWaitingObjects > maxWaitingObjects:
|
||||
maxWaitingObjects = curWaitingObjects
|
||||
if curWaitingObjects > 0:
|
||||
self.statusBar().showMessage(_translate("MainWindow", "Waiting for objects to be sent... %1%").arg(str(50 + 20 * (maxWaitingObjects - curWaitingObjects) / maxWaitingObjects)))
|
||||
time.sleep(0.5)
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
if maxWorkerQueue > 0 or maxWaitingObjects > 0:
|
||||
time.sleep(10) # a bit of time so that the other nodes retrieve the objects
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
|
||||
# save state and geometry self and all widgets
|
||||
self.statusBar().showMessage(_translate("MainWindow", "Saving settings... %1%").arg(str(70)))
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
self.saveSettings()
|
||||
for attr, obj in self.ui.__dict__.iteritems():
|
||||
if hasattr(obj, "__class__") and isinstance(obj, settingsmixin.SettingsMixin):
|
||||
|
@ -2652,19 +2711,20 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if callable (saveMethod):
|
||||
obj.saveSettings()
|
||||
|
||||
self.statusBar().showMessage(_translate("MainWindow", "Shutting down core... %1%").arg(str(80)))
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
shared.doCleanShutdown()
|
||||
self.statusBar().showMessage(_translate("MainWindow", "Stopping notifications... %1%").arg(str(90)))
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
self.tray.hide()
|
||||
# unregister the messaging system
|
||||
if self.mmapp is not None:
|
||||
self.mmapp.unregister()
|
||||
|
||||
# settings = QSettings("Bitmessage", "PyBitmessage")
|
||||
# settings.setValue("geometry", self.saveGeometry())
|
||||
# settings.setValue("state", self.saveState())
|
||||
|
||||
self.statusBar().showMessage(_translate(
|
||||
"MainWindow", "All done. Closing user interface..."))
|
||||
self.statusBar().showMessage(_translate("MainWindow", "Shutdown imminent... %1%").arg(str(100)))
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
shared.thisapp.cleanup()
|
||||
logger.info("Shutdown complete")
|
||||
os._exit(0)
|
||||
|
||||
# window close event
|
||||
|
|
|
@ -47,6 +47,9 @@ class objectHashHolder(threading.Thread):
|
|||
|
||||
def holdPeer(self,peerDetails):
|
||||
self.collectionOfPeerLists[random.randrange(0, self.size)].append(peerDetails)
|
||||
|
||||
def hashCount(self):
|
||||
return sum([len(x) for x in self.collectionOfHashLists])
|
||||
|
||||
def close(self):
|
||||
self.shutdown = True
|
||||
|
|
|
@ -87,7 +87,9 @@ class singleWorker(threading.Thread, StoppableThread):
|
|||
self.sendBroadcast()
|
||||
|
||||
while shared.shutdown == 0:
|
||||
self.busy = 0
|
||||
command, data = shared.workerQueue.get()
|
||||
self.busy = 1
|
||||
if command == 'sendmessage':
|
||||
try:
|
||||
self.sendMsg()
|
||||
|
@ -114,6 +116,7 @@ class singleWorker(threading.Thread, StoppableThread):
|
|||
except:
|
||||
pass
|
||||
elif command == 'stopThread':
|
||||
self.busy = 0
|
||||
return
|
||||
else:
|
||||
logger.error('Probable programming error: The command sent to the workerThread is weird. It is: %s\n' % command)
|
||||
|
|
|
@ -522,6 +522,8 @@ def doCleanShutdown():
|
|||
logger.info('Clean shutdown complete.')
|
||||
thisapp.cleanup()
|
||||
os._exit(0)
|
||||
else:
|
||||
logger.info('Core shutdown complete.')
|
||||
|
||||
# If you want to command all of the sendDataThreads to do something, like shutdown or send some data, this
|
||||
# function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are
|
||||
|
|
Reference in New Issue
Block a user