From 5475060cd9ba00cbac39a7733c41efbaae1a86d9 Mon Sep 17 00:00:00 2001 From: Oleksii Shevchuk Date: Fri, 26 Oct 2018 22:59:52 +0300 Subject: [PATCH] [WIP] exit event: Fig hang during exit event handling --- pupy/network/lib/connection.py | 7 ++++- pupy/pp.py | 52 ++++++++++++++++++++-------------- pupy/pupylib/PupyService.py | 2 ++ 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/pupy/network/lib/connection.py b/pupy/network/lib/connection.py index 56b5eac9..812f0f3c 100644 --- a/pupy/network/lib/connection.py +++ b/pupy/network/lib/connection.py @@ -122,7 +122,8 @@ class SyncRequestDispatchQueue(object): 'Process task(%s) - exception: func=%s args=%s exc:%s/%s', name, func, args, type(e), e) - on_error(e) + if on_error: + on_error(e) del func, args @@ -701,6 +702,10 @@ class PupyConnection(Connection): 'Async timeout! ({}, event={})'.format(self, async_event), async_event) + def defer(self, command, *args): + if not self.closed: + self._queue(command, *args) + def ping(self, timeout=30, now=None, block=False): ''' RPyC do not have any PING handler. So.. why to wait? ''' now = now or time.time() diff --git a/pupy/pp.py b/pupy/pp.py index ae160210..b820d17a 100755 --- a/pupy/pp.py +++ b/pupy/pp.py @@ -143,10 +143,22 @@ if not sys.platform == 'win32' and not pupy.pseudo: ssl.SSLContext.set_default_verify_paths = set_default_verify_paths +def defered_close_exit(connection): + try: + broadcast_event(0x20000000 | 0xFFFF) + except Exception, e: + logger.exception(e) + + logger.debug('Defered close+exit') + sys.terminated = True + connection.close() + def broadcast_event(eventid): if pupy.connection: - logger.debug('Pupy connected: broadcast event via connection (%s). EventId = %08x', - pupy.connection, eventid) + logger.debug( + 'Pupy connected: broadcast event via connection. EventId = %08x', + eventid) + pupy.connection.root.broadcast_event(eventid) elif pupy.broadcast_event: @@ -154,6 +166,7 @@ def broadcast_event(eventid): 'Pupy is not connected, but broadcast_event defined (%s). EventId = %08x', pupy.broadcast_event, eventid) pupy.broadcast_event(eventid) + logger.debug('Pupy connected: broadcast completed') else: logger.debug( 'No way to report event. EventId = %08x', eventid) @@ -482,11 +495,6 @@ class Manager(object): self.pstore.store() - try: - broadcast_event(0x20000000 | 0xFFFF) - except Exception, e: - logger.exception(e) - def safe_obtain(proxy): """ safe version of rpyc's rpyc.utils.classic.obtain, without using pickle. """ @@ -732,24 +740,26 @@ def handle_sighup(signal, frame): def handle_sigterm(signal, frame): logger.warning('SIGTERM') - try: - if hasattr(pupy, 'manager'): - pupy.manager.event(Manager.TERMINATE) + manager = None - except: - print_exception('[ST]') + if hasattr(pupy, 'manager'): + manager = pupy.manager - sys.terminated = True + if manager: + try: + manager.event(Manager.TERMINATE) + except Exception, e: + logger.exception(e) if pupy.connection: - pupy.connection.close() + pupy.connection.defer( + logger.exception, + defered_close_exit, + pupy.connection) + else: + sys.terminated = True - if sys.terminate: - sys.terminate() - - for thread in threading.enumerate(): - if not thread.daemon: - logger.debug('Non daemon thread: %s', thread) + logger.warning('SIGTERM HANDLED') attempt = 0 @@ -944,6 +954,7 @@ def rpyc_loop(launcher): sys.terminate = s.close pupy.connection = s + attempt = 0 s.start() sys.terminate = None @@ -961,7 +972,6 @@ def rpyc_loop(launcher): attempt = 0 pupy.connection = conn - conn.loop() except SystemExit: diff --git a/pupy/pupylib/PupyService.py b/pupy/pupylib/PupyService.py index 6beef6aa..e1b8f6d3 100644 --- a/pupy/pupylib/PupyService.py +++ b/pupy/pupylib/PupyService.py @@ -171,8 +171,10 @@ class PupyService(rpyc.Service): return data def exposed_broadcast_event(self, eventid): + logger.info('Event received: %08x', eventid) if self.events_receiver: self.events_receiver(eventid) + logger.info('Event handled: %08x', eventid) class PupyBindService(PupyService): def exposed_get_password(self):