def shutdown(self, mode=None, _reactor_stopping=False): """ Shuts down the server from inside it. mode - sets the server restart mode. 'reload' - server restarts, no "persistent" scripts are stopped, at_reload hooks called. 'reset' - server restarts, non-persistent scripts stopped, at_shutdown hooks called but sessions will not be disconnected. 'shutdown' - like reset, but server will not auto-restart. None - keep currently set flag from flag file. _reactor_stopping - this is set if server is stopped by a kill command OR this method was already called once - in both cases the reactor is dead/stopping already. """ if _reactor_stopping and hasattr(self, "shutdown_complete"): # this means we have already passed through this method # once; we don't need to run the shutdown procedure again. defer.returnValue(None) mode = self.set_restart_mode(mode) from evennia.objects.models import ObjectDB #from evennia.players.models import PlayerDB from evennia.server.models import ServerConfig if mode == 'reload': # call restart hooks ServerConfig.objects.conf("server_restart_mode", "reload") yield [o.at_server_reload() for o in ObjectDB.get_all_cached_instances()] yield [p.at_server_reload() for p in PlayerDB.get_all_cached_instances()] yield [(s.pause(manual_pause=False), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances() if s.is_active] yield self.sessions.all_sessions_portal_sync() self.at_server_reload_stop() # only save monitor state on reload, not on shutdown/reset from evennia.scripts.monitorhandler import MONITOR_HANDLER MONITOR_HANDLER.save() else: if mode == 'reset': # like shutdown but don't unset the is_connected flag and don't disconnect sessions yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()] yield [p.at_server_shutdown() for p in PlayerDB.get_all_cached_instances()] if self.amp_protocol: yield self.sessions.all_sessions_portal_sync() else: # shutdown yield [_SA(p, "is_connected", False) for p in PlayerDB.get_all_cached_instances()] yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()] yield [(p.unpuppet_all(), p.at_server_shutdown()) for p in PlayerDB.get_all_cached_instances()] yield ObjectDB.objects.clear_all_sessids() yield [(s.pause(manual_pause=False), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()] ServerConfig.objects.conf("server_restart_mode", "reset") self.at_server_cold_stop() # tickerhandler state should always be saved. from evennia.scripts.tickerhandler import TICKER_HANDLER TICKER_HANDLER.save() # always called, also for a reload self.at_server_stop() # if _reactor_stopping is true, reactor does not need to # be stopped again. if os.name == 'nt' and os.path.exists(SERVER_PIDFILE): # for Windows we need to remove pid files manually os.remove(SERVER_PIDFILE) if not _reactor_stopping: # this will also send a reactor.stop signal, so we set a # flag to avoid loops. self.shutdown_complete = True # kill the server reactor.callLater(0, reactor.stop)
def shutdown(self, mode="reload", _reactor_stopping=False): """ Shuts down the server from inside it. mode - sets the server restart mode. 'reload' - server restarts, no "persistent" scripts are stopped, at_reload hooks called. 'reset' - server restarts, non-persistent scripts stopped, at_shutdown hooks called but sessions will not be disconnected. 'shutdown' - like reset, but server will not auto-restart. _reactor_stopping - this is set if server is stopped by a kill command OR this method was already called once - in both cases the reactor is dead/stopping already. """ if _reactor_stopping and hasattr(self, "shutdown_complete"): # this means we have already passed through this method # once; we don't need to run the shutdown procedure again. defer.returnValue(None) from evennia.objects.models import ObjectDB from evennia.server.models import ServerConfig from evennia.utils import gametime as _GAMETIME_MODULE if mode == "reload": # call restart hooks ServerConfig.objects.conf("server_restart_mode", "reload") yield [ o.at_server_reload() for o in ObjectDB.get_all_cached_instances() ] yield [ p.at_server_reload() for p in AccountDB.get_all_cached_instances() ] yield [ (s.pause(manual_pause=False), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances() if s.id and (s.is_active or s.attributes.has("_manual_pause")) ] yield self.sessions.all_sessions_portal_sync() self.at_server_reload_stop() # only save monitor state on reload, not on shutdown/reset from evennia.scripts.monitorhandler import MONITOR_HANDLER MONITOR_HANDLER.save() else: if mode == "reset": # like shutdown but don't unset the is_connected flag and don't disconnect sessions yield [ o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances() ] yield [ p.at_server_shutdown() for p in AccountDB.get_all_cached_instances() ] if self.amp_protocol: yield self.sessions.all_sessions_portal_sync() else: # shutdown yield [ _SA(p, "is_connected", False) for p in AccountDB.get_all_cached_instances() ] yield [ o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances() ] yield [(p.unpuppet_all(), p.at_server_shutdown()) for p in AccountDB.get_all_cached_instances()] yield ObjectDB.objects.clear_all_sessids() yield [( s.pause(manual_pause=s.attributes.get("_manual_pause", False)), s.at_server_shutdown(), ) for s in ScriptDB.get_all_cached_instances()] ServerConfig.objects.conf("server_restart_mode", "reset") self.at_server_cold_stop() # tickerhandler state should always be saved. from evennia.scripts.tickerhandler import TICKER_HANDLER TICKER_HANDLER.save() # always called, also for a reload self.at_server_stop() if hasattr(self, "web_root"): # not set very first start yield self.web_root.empty_threadpool() if not _reactor_stopping: # kill the server self.shutdown_complete = True reactor.callLater(1, reactor.stop) # we make sure the proper gametime is saved as late as possible ServerConfig.objects.conf("runtime", _GAMETIME_MODULE.runtime())