graceful teardown, now with 150% more grace

master
Michał 'rysiek' Woźniak 2015-02-10 22:52:45 +01:00
parent 34c023ad74
commit 4789b0373c
3 changed files with 83 additions and 42 deletions

View File

@ -76,6 +76,12 @@ class ToxManager(mp.Process):
# create the ToxNodes
self._create_toxnodes()
# handling delete in a mature way
def __del__(self):
# yup, just that for now
self._teardown()
# we need some closure
#
@ -125,15 +131,33 @@ class ToxManager(mp.Process):
# let's not over.do() it ;)
sleep(0.03)
# ah, got the teardown flaf
# ah, got the teardown flag -- just inform, proper handling done in finally block below
else:
print('DEBUG :: got teardown, tearing down ToxManager');
print('DEBUG :: got teardown, tearing down ToxManager')
# we don't want no KeyboardInterrupts here, go away.
except KeyboardInterrupt:
print('DEBUG :: ignoring a keyboard interrupt');
print('DEBUG :: ignoring a keyboard interrupt')
# for all other exceptions we need some cleanup/handling code
finally:
# inform
print('DEBUG :: gracefully shutting down all threads')
# set the teardown flag for all processes
self._teardown()
def _teardown(self):
# inform
print('DEBUG :: tearing down all ToxNodes')
for jid in set(self.toxnodes.keys()):
print('DEBUG :: +-- %s' % jid)
del self.toxnodes[jid]
# set the flag just in case
print('DEBUG :: making sure the teardown flag is set')
self.teardown.set()
def get_toxnode(self, jid):
"""

View File

@ -114,40 +114,28 @@ class ToXMPPComponent(ComponentXMPP):
def run(self):
"""
Main queue processing loop
processing as long as teardown mp.Event() flag is not set
"""
while True:
# handle the Tox to XMPP queue items
while not self.t2x_queue.empty():
# yay
tdbg('toxmpp.run() : we got message on the queue!')
try:
while not self.teardown.is_set():
# get the msg
msg = self.t2x_queue.get()
# message? just send it already
if msg['message']:
tdbg('toxmpp.run() : it\'s a message!')
msg = msg['message']
# we have to handle the "from" part -- it contains only the "short" Tox ID:
# https://github.com/irungentoo/toxcore/issues/854
# ...insufficient to build the correct internal JID (these use the "long" version)
# so we have to match it against rosters containing the 'to' external JID
msg['from'] = self.get_jid_from_toxid(msg['from'], msg['to'])
# handle the Tox to XMPP queue items
while not self.t2x_queue.empty():
self.handle_t2x_queue_item(self.t2x_queue.get())
# debug info
tdbg(' +-- from : %(from)s\nTOXMPP :: +-- to : %(to)s\nTOXMPP :: +-- msg : %(body)s' % msg )
tdbg('toxmpp.run() : sending the message out');
self.send_message(mto=msg['to'],
mfrom=msg['from'],
mbody=msg['body'],
mtype='chat') # default type
# wat
else:
raise TypeError('Internal "message" data structure expected expected')
# just you wait
sleep(0.5)
# just you wait
sleep(0.5)
# ah, got the teardown flag -- just inform, proper handling done in finally block below
else:
tdbg('got teardown')
# ach, an exception
finally:
tdbg('tearing down ToXMPPComponent')
# yeah, _teardown() contains everything we need to do
self._teardown()
# getting an internal JID from a ToxID (either "short" or a "full" one)
# for each "short" Tox IDs we might have several different "long" versions
@ -215,17 +203,39 @@ class ToXMPPComponent(ComponentXMPP):
raise ValueError("Valid (long or short) Tox ID expected, '%s' received" % toxid)
def handle_message(self, qitem):
def handle_t2x_queue_item(self, msg):
"""
handling the message stanza
this *should* be a message from an ixternal ToxID-based JID
to an external JID
"""
# forward the message
quitem.send()
# yay
tdbg('toxmpp.run() : we got message on the queue!')
# message? just send it already
if msg['message']:
tdbg('toxmpp.run() : it\'s a message!')
msg = msg['message']
# we have to handle the "from" part -- it contains only the "short" Tox ID:
# https://github.com/irungentoo/toxcore/issues/854
# ...insufficient to build the correct internal JID (these use the "long" version)
# so we have to match it against rosters containing the 'to' external JID
msg['from'] = self.get_jid_from_toxid(msg['from'], msg['to'])
# debug info
tdbg(' +-- from : %(from)s\nTOXMPP :: +-- to : %(to)s\nTOXMPP :: +-- msg : %(body)s' % msg )
tdbg('toxmpp.run() : sending the message out');
self.send_message(mto=msg['to'],
mfrom=msg['from'],
mbody=msg['body'],
mtype='chat') # default type
# wat
else:
raise TypeError('Internal "message" data structure expected expected')
# verify the toxid
def _verify_toxid(self, toxid):
"""
Checking if a given string is a valid ToxID, i.e. is 76 chars
@ -421,14 +431,21 @@ class ToXMPPComponent(ComponentXMPP):
# debug
tdbg('roster\n%s\n' % self.roster)
def _teardown(self):
# tear down the XMPP comms
self.disconnect(wait=True)
# signal the children
self.teardown.set()
# teardown/graceful shutdown
def __del__(self):
# debug
tdbg('tearing down...')
# signal the children
self.teardown.set()
# start teardown
self._teardown()
# join the toxmanager process and give it time to gracefully die
self.toxmanager.join()
@ -501,7 +518,6 @@ if __name__ == '__main__':
except KeyboardInterrupt:
# cleanup
tdbg('KeyboardInterrupt caught, exiting...')
xmpp.disconnect(wait=True)
del xmpp
sys.exit(0)
else:

View File

@ -120,6 +120,7 @@ class ToxNode(Tox):
# handle object teardown
def __del__(self):
print('TOXNODE :: saving the data to: %s' % self.datafile)
# just save the data
self.save_to_file(self.datafile)