def _callback_on_interrupt_callback(cls, sig): cls._condVar.acquire() if cls._destroyed: # # Being destroyed by main thread. # cls._condVar.release() return # For SIGHUP the user callback is always called. It can decide what to do. cls._callbackInProcess = True cls._interrupted = True cls._condVar.release() try: cls._application.interrupt_callback(sig) except Exception as e: Ice.getProcessLogger().error( "{} (while interrupting in response to signal {}): e: {}\n{}". format(cls._app_name, str(sig), e, traceback.format_exc())) cls._condVar.acquire() cls._callbackInProcess = False cls._condVar.notify() cls._condVar.release()
def _post_run_with_session(self): try: self.post_run_with_session() except Exception as e: Ice.getProcessLogger().warning( '{} _post_run_with_session {}\n{}'.format( self.name, e, traceback.format_exc()))
def _do_init_internal(self, init_data): try: self._communicator = Ice.initialize(data=init_data) self._router = Glacier2.RouterPrx.uncheckedCast( self._communicator.getDefaultRouter()) if self._router is None: raise Exception('no glacier2 router configured') try: username, password = self.get_session_username_and_password() self._session = self._router.createSession(username, password) self._is_session_created = True except Ice.LocalException as e: Ice.getProcessLogger().error( 'call create_session failed {}\n{}'.format( e, traceback.format_exc())) raise if self._is_session_created: self._set_acm_setting() self._category = self._router.getCategoryForClient() except Exception as e: Ice.getProcessLogger().error( '_do_init_internal failed : {}'.format(e)) self._do_uninit_internal() raise
def _destroy_on_interrupt_callback(cls, sig): cls._condVar.acquire() if cls._destroyed or cls._nohup and sig == signal.SIGHUP: # # Being destroyed by main thread, or nohup. # cls._condVar.release() return cls._callbackInProcess = True cls._interrupted = True cls._destroyed = True cls._condVar.release() try: cls._communicator.destroy() except Exception as e: Ice.getProcessLogger().error( "{} (while destroying in response to signal {}): e: {}\n{}". format(cls._app_name, str(sig), e, traceback.format_exc())) cls._condVar.acquire() cls._callbackInProcess = False cls._condVar.notify() cls._condVar.release()
def _do_uninit_internal(self): if self._router: if self._is_session_created: self._is_session_created = False try: self._router.destroySession() except (Ice.ConnectionLostException, SessionNotExistException): pass except Exception as e: Ice.getProcessLogger().error( 'unexpected exception when destroying the session {}\n{}' .format(e, traceback.format_exc())) self._router = None if self._communicator: try: self._communicator.destroy() except Exception as e: Ice.getProcessLogger().error( 'unexpected exception when destroying the communicator {}\n{}' .format(e, traceback.format_exc())) self._communicator = None self._adapter = None self._router = None self._session = None self._createdSession = False self._category = None
def _set_exception(self, e): if isinstance(e, SessionCancelException): # 主动取消的优先级最高 self.exception = e elif self.exception is None: self.exception = e else: # 仅记录最初始的异常 Ice.getProcessLogger().trace( None, '{} ignore record {}'.format(self.name, e))
def callback_on_interrupt(cls): """Configures the application to invoke interrupt_callback when interrupted by a signal.""" if Application._signalPolicy == Application.HandleSignals: cls._condVar.acquire() if cls._ctrlCHandler.getCallback() == cls._hold_interrupt_callback: cls._released = True cls._condVar.notify() cls._ctrlCHandler.setCallback(cls._callback_on_interrupt_callback) cls._condVar.release() else: Ice.getProcessLogger().error("interrupt method called on Application configured to not handle interrupts.")
def run(self): try: while self._run_continue: if self.session_exist: self._run_with_session() else: self._create_new_session() except SessionCancelException: pass # do nothing finally: Ice.getProcessLogger().warning('{} exit'.format(self.name))
def stop(self): """停止连接 :remark: 异步,不等待连接停止 """ Ice.getProcessLogger().trace(None, '{} set quit flag'.format(self.name)) self._quit_cond.acquire() self._quit = True self._quit_cond.notify_all() self._quit_cond.release()
def hold_interrupt(cls): """Configures the application to queue an interrupt for later processing.""" if Application._signalPolicy == Application.HandleSignals: cls._condVar.acquire() if cls._ctrlCHandler.getCallback() != cls._hold_interrupt_callback: cls._previousCallback = cls._ctrlCHandler.getCallback() cls._released = False cls._ctrlCHandler.setCallback(cls._hold_interrupt_callback) # else, we were already holding signals cls._condVar.release() else: Ice.getProcessLogger().error("interrupt method called on Application configured to not handle interrupts.")
def release_interrupt(cls): """Instructs the application to process any queued interrupt.""" if Application._signalPolicy == Application.HandleSignals: cls._condVar.acquire() if cls._ctrlCHandler.getCallback() == cls._hold_interrupt_callback: # # Note that it's very possible no signal is held; # in this case the callback is just replaced and # setting _released to true and signalling _condVar # do no harm. # cls._released = True cls._ctrlCHandler.setCallback(cls._previousCallback) cls._condVar.notify() # Else nothing to release. cls._condVar.release() else: Ice.getProcessLogger().error("interrupt method called on Application configured to not handle interrupts.")
def _create_new_session(self): init_data = Application.generate_init_data(self.config_file, self.init_data_list, None) try: self._do_init_internal(init_data) except RestartSessionException: self._do_uninit_internal() pass # do nothing except (Ice.ConnectionRefusedException, Ice.ConnectionLostException, Ice.UnknownLocalException, Ice.RequestFailedException, Ice.TimeoutException) as e: Ice.getProcessLogger().error('{} init net {}\n{}'.format( self.name, e, traceback.format_exc())) self._do_uninit_internal() pass # do nothing except Exception as e: Ice.getProcessLogger().error('{} failed {}\n{}'.format( self.name, e, traceback.format_exc())) self._set_exception(e)
def start(self): """连接到透传网关 :remark: 当首次连接失败时,抛出异常 当运行过程中链路断开后,会进行自动重连 """ init_data = Application.generate_init_data(self.config_file, self.init_data_list, None) self._do_init_internal(init_data) Ice.getProcessLogger().trace(None, '{} init ok'.format(self.name)) try: super(GlacierSession, self).start() except Exception as e: Ice.getProcessLogger().error('{} start failed {}\n{}'.format( self.name, e, traceback.format_exc())) self._do_uninit_internal() raise
def do_main(self, args, init_data): try: Application._communicator = Ice.initialize(args, init_data) Application._destroyed = False status = self.run(args) except Exception as e: Ice.getProcessLogger().error('{}\n{}'.format( e, traceback.format_exc())) status = 1 # # Don't want any new interrupt and at this point (post-run), # it would not make sense to release a held signal to run # shutdown or destroy. # if Application._signalPolicy == Application.HandleSignals: Application.ignore_interrupt() Application._condVar.acquire() while Application._callbackInProgress: Application._condVar.wait() if Application._destroyed: Application._communicator = None else: Application._destroyed = True # # And _communicator != 0, meaning will be destroyed # next, _destroyed = true also ensures that any # remaining callback won't do anything # Application._application = None Application._condVar.release() if Application._communicator: try: Application._communicator.destroy() except Exception as e: Ice.getProcessLogger().error( 'destroy _communicator exception {}\n{}'.format( e, traceback.format_exc())) status = 1 Application._communicator = None return status
def _run_with_session(self): try: self.run_with_session() while self._need_running(): self.heartbeat_check() raise SessionCancelException() # We want to restart on those exceptions which indicate a # break down in communications, but not those exceptions that # indicate a programming logic error (ie: marshal, protocol # failure, etc). except SessionCancelException as sce: Ice.getProcessLogger().warning('{} SessionCancelException'.format( self.name)) self._set_exception(sce) except RestartSessionException: pass # do nothing except (Ice.ConnectionRefusedException, Ice.ConnectionLostException, Ice.UnknownLocalException, Ice.RequestFailedException, Ice.TimeoutException) as e: Ice.getProcessLogger().error('{} run net {}\n{}'.format( self.name, e, traceback.format_exc())) pass # do nothing except Exception as e: Ice.getProcessLogger().error('{} failed {}\n{}'.format( self.name, e, traceback.format_exc())) self._set_exception(e) finally: self._post_run_with_session() self._do_uninit_internal()
def _logger(obj, cond): """Private function for internal use.""" if obj is None: if cond: return Ice.getProcessLogger() else: return None elif isinstance(obj, Ice.Logger): if cond: return obj else: return None elif isinstance(obj, Ice.Communicator): return _logger_from_communicator(obj, cond) elif isinstance(obj, Ice.Current): return _logger_from_communicator(obj.adapter.getCommunicator(), cond) else: raise TypeError("Could not get logger from object %s" % obj)
def __del__(self): if self.session_exist: Ice.getProcessLogger().error('{} not uninit !!!!'.format( self.name)) self._do_uninit_internal() Ice.getProcessLogger().trace(None, '{} __del__'.format(self.name))
def doMainInternal(self, args, initData): # Reset internal state variables from Ice.Application. The # remainder are reset at the end of this method. Ice.Application._callbackInProgress = False Ice.Application._destroyed = False Ice.Application._interrupted = False restart = False status = 0 ping = None try: Ice.Application._communicator = Ice.initialize(args, initData) Application._router = RouterPrx.uncheckedCast(Ice.Application.communicator().getDefaultRouter()) if Application._router == None: Ice.getProcessLogger().error("no glacier2 router configured") status = 1 else: # # The default is to destroy when a signal is received. # if Ice.Application._signalPolicy == Ice.Application.HandleSignals: Ice.Application.destroyOnInterrupt() # If createSession throws, we're done. try: Application._session = self.createSession() Application._createdSession = True except Ice.LocalException: Ice.getProcessLogger().error(traceback.format_exc()) status = 1 if Application._createdSession: ping = SessionPingThread(self, Application._router, Application._router.getSessionTimeout() / 2) ping.start() Application._category = Application._router.getCategoryForClient() status = self.runWithSession(args) # We want to restart on those exceptions which indicate a # break down in communications, but not those exceptions that # indicate a programming logic error (ie: marshal, protocol # failure, etc). except(RestartSessionException): restart = True except(Ice.ConnectionRefusedException, Ice.ConnectionLostException, Ice.UnknownLocalException, \ Ice.RequestFailedException, Ice.TimeoutException): Ice.getProcessLogger().error(traceback.format_exc()) restart = True except: Ice.getProcessLogger().error(traceback.format_exc()) status = 1 # # Don't want any new interrupt and at this point (post-run), # it would not make sense to release a held signal to run # shutdown or destroy. # if Ice.Application._signalPolicy == Ice.Application.HandleSignals: Ice.Application.ignoreInterrupt() Ice.Application._condVar.acquire() while Ice.Application._callbackInProgress: Ice.Application._condVar.wait() if Ice.Application._destroyed: Ice.Application._communicator = None else: Ice.Application._destroyed = True # # And _communicator != None, meaning will be destroyed # next, _destroyed = True also ensures that any # remaining callback won't do anything # Ice.Application._condVar.release() if ping: ping.done() ping.join() if Application._createdSession and Application._router: try: Application._router.destroySession() except (Ice.ConnectionLostException, SessionNotExistException): pass except: Ice.getProcessLogger().error("unexpected exception when destroying the session " + \ traceback.format_exc()) Application._router = None if Ice.Application._communicator: try: Ice.Application._communicator.destroy() except: getProcessLogger().error(traceback.format_exc()) status = 1 Ice.Application._communicator = None # Reset internal state. We cannot reset the Application state # here, since _destroyed must remain true until we re-run # this method. Application._adapter = None Application._router = None Application._session = None Application._createdSession = False Application._category = None return (restart, status)
def closed(self, conn): Ice.getProcessLogger().warning('{} connect closed {}'.format( self._app.name, conn)) self._app.connection_closed()
def main(self, args: list, config_file: str, init_data_list: list, logger): """The main entry point for the Application class. :param args: The arguments are an argument list (such as sys.argv), 最高优先级 :param config_file: The file path of an Ice configuration file,次优先级 :param init_data_list: InitializationData properties 参数,最低优先级 [('Ice.Default.Host', '127.0.0.1'), ('Ice.Warn.Connections', '1'), ... ] :param logger: python 的标准库 logger 对象 :return: This method does not return until after the completion of the run method. The return value is an integer representing the exit status. """ if Application._communicator: Ice.getProcessLogger().error( args[0] + ": only one instance of the Application class can be used") return 1 Ice.setProcessLogger(_ApplicationLoggerI(logger)) # # We parse the properties here to extract Ice.ProgramName. # init_data = self.generate_init_data(config_file, init_data_list, args) # # Install our handler for the signals we are interested in. We assume main() is called from the main thread. # if Application._signalPolicy == Application.HandleSignals: Application._ctrlCHandler = Ice.CtrlCHandler() try: Application._interrupted = False Application._app_name = \ init_data.properties.getPropertyWithDefault("Ice.ProgramName", args[0]) Application._application = self # # Used by _destroy_on_interrupt_callback and _shutdown_on_interrupt_callback. # Application._nohup = init_data.properties.getPropertyAsInt( "Ice.Nohup") > 0 # # The default is to destroy when a signal is received. # if Application._signalPolicy == Application.HandleSignals: Application.destroy_on_interrupt() status = self.do_main(args, init_data) except Exception as e: Ice.getProcessLogger().error('main loop exception {}\n{}'.format( e, traceback.format_exc())) status = 1 # # Set _ctrlCHandler to 0 only once communicator.destroy() has completed. # if Application._signalPolicy == Application.HandleSignals: Application._ctrlCHandler.destroy() Application._ctrlCHandler = None return status