mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Add external-runner option to the launcher to allow for replacing the native evennia runner with an external process manager (like Linux' start-stop-daemon). Note that without a replacement, this option will make evennia un-reloadable.
This commit is contained in:
parent
ad13594a46
commit
293c3b077d
2 changed files with 29 additions and 7 deletions
|
|
@ -1084,7 +1084,7 @@ def run_menu():
|
|||
return
|
||||
|
||||
|
||||
def server_operation(mode, service, interactive, profiler, logserver=False):
|
||||
def server_operation(mode, service, interactive, profiler, logserver=False, doexit=False):
|
||||
"""
|
||||
Handle argument options given on the command line.
|
||||
|
||||
|
|
@ -1095,6 +1095,10 @@ def server_operation(mode, service, interactive, profiler, logserver=False):
|
|||
profiler (bool): Run the service under the profiler.
|
||||
logserver (bool, optional): Log Server data to logfile
|
||||
specified by settings.SERVER_LOG_FILE.
|
||||
doexit (bool, optional): If True, immediately exit the runner after
|
||||
starting the relevant processes. If the runner exits, Evennia
|
||||
cannot be reloaded. This is meant to be used with an external
|
||||
process manager like Linux' start-stop-daemon.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -1136,6 +1140,8 @@ def server_operation(mode, service, interactive, profiler, logserver=False):
|
|||
cmdstr.append('--logserver')
|
||||
django.core.management.call_command(
|
||||
'collectstatic', verbosity=1, interactive=False)
|
||||
if doexit:
|
||||
cmdstr.append('--doexit')
|
||||
cmdstr.extend([
|
||||
GAMEDIR, TWISTED_BINARY, SERVER_LOGFILE,
|
||||
PORTAL_LOGFILE, HTTP_LOGFILE])
|
||||
|
|
@ -1242,6 +1248,10 @@ def main():
|
|||
'--initsettings', action='store_true', dest="initsettings",
|
||||
default=False,
|
||||
help="Create a new, empty settings file as gamedir/server/conf/settings.py.")
|
||||
parser.add_argument(
|
||||
'--external-runner', action='store_true', dest="doexit",
|
||||
default=False,
|
||||
help="Handle server restart with an external process manager.")
|
||||
parser.add_argument(
|
||||
"operation", nargs='?', default="noop",
|
||||
help="Operation to perform: 'start', 'stop', 'reload' or 'menu'.")
|
||||
|
|
@ -1315,7 +1325,7 @@ def main():
|
|||
elif option in ('start', 'reload', 'stop'):
|
||||
# operate the server directly
|
||||
init_game_directory(CURRENT_DIR, check_db=True)
|
||||
server_operation(option, service, args.interactive, args.profiler, args.logserver)
|
||||
server_operation(option, service, args.interactive, args.profiler, args.logserver, doexit=args.doexit)
|
||||
elif option != "noop":
|
||||
# pass-through to django manager
|
||||
check_db = False
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ PROCESS_IOERROR = \
|
|||
|
||||
PROCESS_RESTART = "{component} restarting ..."
|
||||
|
||||
PROCESS_DOEXIT = "Deferring to external runner."
|
||||
|
||||
# Functions
|
||||
|
||||
|
|
@ -134,7 +135,7 @@ def cycle_logfile(logfile):
|
|||
# Start program management
|
||||
|
||||
|
||||
def start_services(server_argv, portal_argv):
|
||||
def start_services(server_argv, portal_argv, doexit=False):
|
||||
"""
|
||||
This calls a threaded loop that launces the Portal and Server
|
||||
and then restarts them when they finish.
|
||||
|
|
@ -162,7 +163,7 @@ def start_services(server_argv, portal_argv):
|
|||
|
||||
if portal_argv:
|
||||
try:
|
||||
if get_restart_mode(PORTAL_RESTART) == "True":
|
||||
if not doexit and get_restart_mode(PORTAL_RESTART) == "True":
|
||||
# start portal as interactive, reloadable thread
|
||||
PORTAL = thread.start_new_thread(portal_waiter, (processes, ))
|
||||
else:
|
||||
|
|
@ -175,12 +176,19 @@ def start_services(server_argv, portal_argv):
|
|||
|
||||
try:
|
||||
if server_argv:
|
||||
# start server as a reloadable thread
|
||||
SERVER = thread.start_new_thread(server_waiter, (processes, ))
|
||||
if doexit:
|
||||
SERVER = Popen(server_argv, env=getenv())
|
||||
else:
|
||||
# start server as a reloadable thread
|
||||
SERVER = thread.start_new_thread(server_waiter, (processes, ))
|
||||
except IOError as e:
|
||||
print(PROCESS_IOERROR.format(component="Server", traceback=e))
|
||||
return
|
||||
|
||||
if doexit:
|
||||
# Exit immediately
|
||||
return
|
||||
|
||||
# Reload loop
|
||||
while True:
|
||||
|
||||
|
|
@ -234,6 +242,8 @@ def main():
|
|||
default=False, help='Profile Portal')
|
||||
parser.add_argument('--nologcycle', action='store_false', dest='nologcycle',
|
||||
default=True, help='Do not cycle log files')
|
||||
parser.add_argument('--doexit', action='store_true', dest='doexit',
|
||||
default=False, help='Immediately exit after processes have started.')
|
||||
parser.add_argument('gamedir', help="path to game dir")
|
||||
parser.add_argument('twistdbinary', help="path to twistd binary")
|
||||
parser.add_argument('slogfile', help="path to server log file")
|
||||
|
|
@ -327,6 +337,8 @@ def main():
|
|||
if args.pportal:
|
||||
portal_argv.extend(pportal_argv)
|
||||
print("\nRunning Evennia Portal under cProfile.")
|
||||
if args.doexit:
|
||||
print(PROCESS_DOEXIT)
|
||||
|
||||
# Windows fixes (Windows don't support pidfiles natively)
|
||||
if os.name == 'nt':
|
||||
|
|
@ -336,7 +348,7 @@ def main():
|
|||
del portal_argv[-2]
|
||||
|
||||
# Start processes
|
||||
start_services(server_argv, portal_argv)
|
||||
start_services(server_argv, portal_argv, doexit=args.doexit)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue