Crash hugvey client on exception so it can be restarted by supervisor

This commit is contained in:
Ruben van de Ven 2019-05-01 13:08:41 +02:00
parent 062f056e96
commit ef7eee8072
2 changed files with 61 additions and 14 deletions

View file

@ -463,10 +463,10 @@ class Hugvey(object):
def start(self):
logger.debug('Hugvey {}, reporting'.format(self.id))
loop = asyncio.get_event_loop()
self.loop = asyncio.get_event_loop()
self.voice_server = VoiceServer(
loop=loop,
loop=self.loop,
hugvey=self,
config=self.config
)
@ -483,9 +483,18 @@ class Hugvey(object):
logger.info('start')
# self.voice_server.asyncStart(loop)
# loop.run_until_complete(self.voice_server.start())
asyncio.ensure_future(self.voice_server.start())
asyncio.ensure_future(self.cmd_server.command_listener())
asyncio.ensure_future(self.cmd_server.event_sender())
asyncio.ensure_future(self.cmd_server.heartbeat())
loop.run_forever()
asyncio.ensure_future(self.catchException(self.voice_server.start()))
asyncio.ensure_future(self.catchException(self.cmd_server.command_listener()))
asyncio.ensure_future(self.catchException(self.cmd_server.event_sender()))
asyncio.ensure_future(self.catchException(self.cmd_server.heartbeat()))
self.loop.run_forever()
logger.info('done')
async def catchException(self, awaitable):
try:
await awaitable
except Exception as e:
logger.exception(e)
logger.critical("Hugvey quiting")
# self.loop.stop() # not fully quits program for reboot
exit()

View file

@ -485,6 +485,8 @@ class Diversion(object):
self.params = params
self.finaliseMethod = None
self.hasHit = False
self.disabled = False
self.type = type
if type == 'no_response':
self.method = self._divergeIfNoResponse
self.finaliseMethod = self._returnAfterNoResponse
@ -532,6 +534,7 @@ class Diversion(object):
story.logger.warn(f"Invalid message selected for diversion: {self.params['notAfterMsgId']} for {self.id}")
elif story.logHasMsg(msg):
# story.logger.warn(f"Block diversion {self.id} because of hit message {self.params['notAfterMsgId']}")
self.disabled = True # never run it and allow following timeouts/no_responses to run
return False
r = await self.method(story,
@ -539,7 +542,10 @@ class Diversion(object):
direction.msgTo if direction else None,
direction if direction else None)
if r:
if self.type != 'repeat':
# repeat diversion should be usable infinte times
self.hasHit = True
story.addToLog(self)
return r
@ -616,7 +622,7 @@ class Diversion(object):
if story.currentDiversion or not msgFrom or not msgTo:
return False
if story.stats['diversions']['no_response'] + 1 == self.params['timesOccured'] and story.stats['consecutiveSilentTimeouts'] >= int(self.params['consecutiveSilences']):
if story.stats['consecutiveSilentTimeouts'] >= int(self.params['consecutiveSilences']):
story.stats['diversions']['no_response'] += 1
msg = story.get(self.params['msgId'])
if msg is None:
@ -740,8 +746,6 @@ class Diversion(object):
interval = float(self.params['interval'])
if not self.params['fromLastMessage']:
# (1) last spoken at all
if story.stats['diversions']['timeout_total'] + 1 != self.params['timesOccured']:
return
timeSince = story.timer.getElapsed('last_speech') if story.timer.hasMark('last_speech') else story.timer.getElapsed('start')
if story.timer.hasMark('last_diversion_timeout') and story.timer.getElapsed('last_diversion_timeout') > timeSince:
@ -755,8 +759,6 @@ class Diversion(object):
return
# if story.currentMessage.timeoutDiversionCount + 1
if story.stats['diversions']['timeout_last'] + 1 != self.params['timesOccured']:
return
if story.currentReply is not None:
# still playing back
@ -974,7 +976,6 @@ class Story(object):
self.logger.info(f'has variables: {self.variables}')
self.logger.info(f'has {len(self.strands)} strands: {self.strands}')
self.calculateFinishesForStrands()
self.logger.warn("Calculated strands!")
def reset(self):
self.timer.reset()
@ -1172,7 +1173,44 @@ class Story(object):
Else, they are None
"""
diverge = False
activeDiversions = []
activeTimeoutDiv = None
activeTimeoutLastDiv = None
activeNoResponseDiv = None
for diversion in self.diversions:
#: :type diversion: Diversion
if diversion.disabled or diversion.hasHit:
continue
if diversion.type == 'timeout':
if diversion.params['timesOccured'] > 0:
if not diversion.params['fromLastMessage']:
# perhaps neater if we collect them in a list, and then sort by key, but this works just as well
if not activeTimeoutDiv or activeTimeoutDiv.params['timesOccured'] > diversion.params['timesOccured']:
activeTimeoutDiv = diversion
else:
if not activeTimeoutLastDiv or activeTimeoutLastDiv.params['timesOccured'] > diversion.params['timesOccured']:
activeTimeoutLastDiv = diversion
continue
if diversion.type == 'no_response':
if diversion.params['timesOccured'] > 0:
if not activeNoResponseDiv or activeNoResponseDiv.params['timesOccured'] > diversion.params['timesOccured']:
activeNoResponseDiv = diversion
continue
activeDiversions.append(diversion)
if activeTimeoutDiv:
activeDiversions.append(activeTimeoutDiv)
if activeTimeoutLastDiv:
activeDiversions.append(activeTimeoutLastDiv)
if activeNoResponseDiv:
activeDiversions.append(activeNoResponseDiv)
for diversion in activeDiversions:
# TODO: collect diversions and order by times + timesOccured (for timeout & no_response)
d = await diversion.divergeIfNeeded(self, direction)
if d:
diverge = True