Reworked server reboot code to make the cold reset function work as documented and not disconnect any sessions. Resolves #742.

This commit is contained in:
Griatch 2015-05-14 20:18:39 +02:00
parent 3410499313
commit 33154d4d60
2 changed files with 31 additions and 19 deletions

View file

@ -65,10 +65,18 @@ class CmdReset(MuxCommand):
Usage: Usage:
@reset @reset
A cold reboot. This works like a mixture of @reload and @shutdown, Notes:
- all shutdown hooks will be called and non-persistent scripts will For normal updating you are recommended to use @reload rather
be purged. But the Portal will not be affected and the server will than this command. Use @shutdown for a complete stop of
automatically restart again. everything.
This emulates a cold reboot of the Server component of Evennia.
The difference to @shutdown is that the Server will auto-reboot
and that it does not affect the Portal, so no users will be
disconnected. Contrary to @reload however, all shutdown hooks will
be called and any non-database saved scripts, ndb-attributes,
cmdsets etc will be wiped.
""" """
key = "@reset" key = "@reset"
aliases = ['@reboot'] aliases = ['@reboot']

View file

@ -285,6 +285,9 @@ class Evennia(object):
if mode in ('True', 'reload'): if mode in ('True', 'reload'):
# True was the old reload flag, kept for compatibilty # True was the old reload flag, kept for compatibilty
self.at_server_reload_start() self.at_server_reload_start()
elif mode == 'reset':
# only run hook, don't purge sessions
self.at_server_cold_start()
elif mode in ('reset', 'shutdown'): elif mode in ('reset', 'shutdown'):
self.at_server_cold_start() self.at_server_cold_start()
# clear eventual lingering session storages # clear eventual lingering session storages
@ -320,7 +323,8 @@ class Evennia(object):
'reload' - server restarts, no "persistent" scripts 'reload' - server restarts, no "persistent" scripts
are stopped, at_reload hooks called. are stopped, at_reload hooks called.
'reset' - server restarts, non-persistent scripts stopped, 'reset' - server restarts, non-persistent scripts stopped,
at_shutdown hooks called. at_shutdown hooks called but sessions will not
be disconnected.
'shutdown' - like reset, but server will not auto-restart. 'shutdown' - like reset, but server will not auto-restart.
None - keep currently set flag from flag file. None - keep currently set flag from flag file.
_reactor_stopping - this is set if server is stopped by a kill _reactor_stopping - this is set if server is stopped by a kill
@ -334,7 +338,6 @@ class Evennia(object):
defer.returnValue(None) defer.returnValue(None)
mode = self.set_restart_mode(mode) mode = self.set_restart_mode(mode)
# call shutdown hooks on all cached objects
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
#from evennia.players.models import PlayerDB #from evennia.players.models import PlayerDB
@ -342,38 +345,38 @@ class Evennia(object):
if mode == 'reload': if mode == 'reload':
# call restart hooks # call restart hooks
ServerConfig.objects.conf("server_restart_mode", "reload")
yield [o.at_server_reload() for o in ObjectDB.get_all_cached_instances()] 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 [p.at_server_reload() for p in PlayerDB.get_all_cached_instances()]
yield [(s.pause(), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances()] yield [(s.pause(), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances()]
yield self.sessions.all_sessions_portal_sync() yield self.sessions.all_sessions_portal_sync()
ServerConfig.objects.conf("server_restart_mode", "reload") self.at_server_reload_stop()
# only save OOB state on reload, not on shutdown/reset
from evennia.server.oobhandler import OOB_HANDLER from evennia.server.oobhandler import OOB_HANDLER
OOB_HANDLER.save() OOB_HANDLER.save()
from evennia.scripts.tickerhandler import TICKER_HANDLER
TICKER_HANDLER.save()
self.at_server_reload_stop()
else: else:
ServerConfig.objects.conf("server_restart_mode", "reset")
if mode == 'reset': if mode == 'reset':
# don't unset the is_connected flag on reset, otherwise # like shutdown but don't unset the is_connected flag and don't disconnect sessions
# same as shutdown
yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()] 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()] yield [p.at_server_shutdown() for p in PlayerDB.get_all_cached_instances()]
yield self.sessions.all_sessions_portal_sync()
else: # shutdown else: # shutdown
yield [_SA(p, "is_connected", False) for p in PlayerDB.get_all_cached_instances()] 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 [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()]
yield [(p.unpuppet_all(), p.at_server_shutdown()) yield [(p.unpuppet_all(), p.at_server_shutdown())
for p in PlayerDB.get_all_cached_instances()] for p in PlayerDB.get_all_cached_instances()]
yield [(s.pause(), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances()]
yield [s.at_server_shutdown() for s in ScriptDB.get_all_cached_instances()]
yield ObjectDB.objects.clear_all_sessids() yield ObjectDB.objects.clear_all_sessids()
ServerConfig.objects.conf("server_restart_mode", "reset") yield [(s.pause(), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances()]
self.at_server_cold_stop() 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() self.at_server_stop()
# if _reactor_stopping is true, reactor does not need to # if _reactor_stopping is true, reactor does not need to
# be stopped again. # be stopped again.
if os.name == 'nt' and os.path.exists(SERVER_PIDFILE): if os.name == 'nt' and os.path.exists(SERVER_PIDFILE):
@ -383,6 +386,7 @@ class Evennia(object):
# this will also send a reactor.stop signal, so we set a # this will also send a reactor.stop signal, so we set a
# flag to avoid loops. # flag to avoid loops.
self.shutdown_complete = True self.shutdown_complete = True
# kill the server
reactor.callLater(0, reactor.stop) reactor.callLater(0, reactor.stop)
# server start/stop hooks # server start/stop hooks