Changing server script to write unbuffered to stderr and added stress-test server option

This commit is contained in:
Eric Froemling 2021-02-25 17:59:42 -06:00
parent 8ccc5eeef8
commit 2c421f5420
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
9 changed files with 137 additions and 77 deletions

View File

@ -3932,26 +3932,26 @@
"assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450", "assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450",
"assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e", "assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e",
"assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f", "assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f",
"build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/61/c1/35c60d99bf4867eada2b7ad0dc19", "build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/76/e4/20e36d3f74b4aba6dfbf6c1e7a3c",
"build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/64/f43f7baf75512685ac0dce8e0f1c", "build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9f/3b/46c10e31faf30642719e8d051f51",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ce/75/e25f75557b05b0de2ab4a281c0de", "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3c/a7/3ca43775dfe81d796bfa38473303",
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/32/c6/4503e9fd3e6d7a27e7e1f32f8542", "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/51/ec/c4ebc76cd5f17f974874bcfc7733",
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6b/b7/47e4719f2aef688e62ad2f416406", "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/98/f3/55d5e976bf4a5e59b7fb0e1a9049",
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/93/85/c5c09d5fe4e13655ccb021c44d5a", "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9d/cf/1abae2d413903ac980e3cfd6e0e3",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/42/7f/46fd7611f88f659d27e827a58c8f", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1c/3c/161096b136ac519eaf7ead0d32a1",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3e/02/5e9b6ffdc3e242e1ddbcc67c027a", "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/13/1c/c72c01e8e7ed072b2452142fca77",
"build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/dc/6d/0a0a41762f27f0f8cdd2a7d2c033", "build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d6/9d/e4a6554a9712cda7840511219df2",
"build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1d/37/11d275e939854da3e1488360d1fd", "build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c8/ca/e686c76cc102db57c4df20a0db04",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/63/26/e9e64910b7e242129c5006234116", "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/59/c272db6020c424a96ce01a4f5d56",
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8b/9c/edb852a4d5c7304e39e9618bca93", "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8a/87/7bbc845d3559609d1b5a411d12e2",
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/22/fb/29e80f93d3899abc57854b3dbe52", "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/5b/77/f45ffd7e36bf3e86d8c8c01c5b72",
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c7/fc/4e3c1cfce367e5ace09e5bcbe9fc", "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/83/97/446ffe1f9e6a762d8f006b264654",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9f/ee/ec4ed4396a600c69202566f2713d", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2b/29/785e06a7b25ed5b55a9d0e93c6bf",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6e/1c/0d1f8e451d24591b27f15f26a827", "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c2/ef/3cade90a38e855c8dc9c15295c32",
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d1/79/d3cb45d123726fac04611ce103f9", "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d6/c9/3e3a70a888a785a4f0e9dd483a1f",
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/70/2a/a1db2d042bbe3c319b2a4bc6c395", "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/8a/1b/4fdf49299324c76e637777ea7e4a",
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/f5/8c/bd7cb4286e0dadf7b29211a95560", "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/57/48/fab31e4ac7d9f846245ebaf6fe0a",
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/4c/62/5797c0590d0128637c419f74cb67", "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/e8/b0/841559924243fcada9d7d1cb58de",
"build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/bf/393694ea67f3d590dd2706c9955e", "build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/bf/393694ea67f3d590dd2706c9955e",
"build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/78/cb/bb9ae4f896f862074057c8e36e1d", "build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/78/cb/bb9ae4f896f862074057c8e36e1d",
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ae/bd/39d7b885f7f01e81d0e96f0f85ce", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ae/bd/39d7b885f7f01e81d0e96f0f85ce",
@ -3960,12 +3960,12 @@
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/d9/563a6949d2c4db5a915c54460fbc", "build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/d9/563a6949d2c4db5a915c54460fbc",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/6a/42fe8d2e34f95e1b3282e8422344", "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/6a/42fe8d2e34f95e1b3282e8422344",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/50/cf/bad44b07a4022aee3001002086b5", "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/50/cf/bad44b07a4022aee3001002086b5",
"build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/bd/bc/1e305f3aafb660b0f45256fd07d1", "build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/38/dc/ac069b31a566df1b738adae005b6",
"build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ea/0e/42b6ec781850c69e6bab8e1b14f6", "build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c9/96/a75c9739a5cccca60cd74cea22ca",
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/92/84/7e78c73d0c91d45f92f795155d5f", "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3c/17/f1b4bb490383d9dc43714f39c77b",
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b9/4e/9fe6ea82f278ace93e724253df84", "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c2/e0/32f9701738320d592692e9b30869",
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/15/a4/7e2d2dbc870b286358d34b6e6cee", "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/98/43/d779605636305318e68d4eaef10a",
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e3/10/4e2baf04c93a5bc632bdbd7e92f6", "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/28/b2/7ce9803bf834bf90f3d5927c323e",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/23/f4/c55e363bb00319971d21b2382431", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/be/e4/e37e38122257176c923475c4be83",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/27/2f/c8895ca79eb249a959578a203ff7" "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/eb/51/2ca27968b65c54abe198ff49f164"
} }

View File

@ -335,8 +335,16 @@ class ServerController:
_ba.set_public_party_stats_url(self._config.stats_url) _ba.set_public_party_stats_url(self._config.stats_url)
_ba.set_public_party_enabled(self._config.party_is_public) _ba.set_public_party_enabled(self._config.party_is_public)
# And here we go. # And here.. we.. go.
_ba.new_host_session(sessiontype) if self._config.stress_test_players is not None:
# Special case: run a stress test.
from ba.internal import run_stress_test
run_stress_test(playlist_type='Random',
playlist_name='__default__',
player_count=self._config.stress_test_players,
round_duration=30)
else:
_ba.new_host_session(sessiontype)
# Run an access check if we're trying to make a public party. # Run an access check if we're trying to make a public party.
if not self._ran_access_check and self._config.party_is_public: if not self._ran_access_check and self._config.party_is_public:

View File

@ -116,8 +116,11 @@ class ServerManagerApp:
self._running = True self._running = True
dbgstr = 'debug' if __debug__ else 'opt' dbgstr = 'debug' if __debug__ else 'opt'
print(f'{Clr.CYN}{Clr.BLD}BallisticaCore server manager {VERSION_STR}' print(
f' starting up ({dbgstr} mode)...{Clr.RST}') f'{Clr.CYN}{Clr.BLD}BallisticaCore server manager {VERSION_STR}'
f' starting up ({dbgstr} mode)...{Clr.RST}',
file=sys.stderr,
flush=True)
# Python will handle SIGINT for us (as KeyboardInterrupt) but we # Python will handle SIGINT for us (as KeyboardInterrupt) but we
# need to register a SIGTERM handler so we have a chance to clean # need to register a SIGTERM handler so we have a chance to clean
@ -136,11 +139,15 @@ class ServerManagerApp:
def _postrun(self) -> None: def _postrun(self) -> None:
"""Common code at the end of any run.""" """Common code at the end of any run."""
print(f'{Clr.CYN}Server manager shutting down...{Clr.RST}') print(f'{Clr.CYN}Server manager shutting down...{Clr.RST}',
file=sys.stderr,
flush=True)
assert self._subprocess_thread is not None assert self._subprocess_thread is not None
if self._subprocess_thread.is_alive(): if self._subprocess_thread.is_alive():
print(f'{Clr.CYN}Waiting for subprocess exit...{Clr.RST}') print(f'{Clr.CYN}Waiting for subprocess exit...{Clr.RST}',
file=sys.stderr,
flush=True)
# Mark ourselves as shutting down and wait for the process to wrap up. # Mark ourselves as shutting down and wait for the process to wrap up.
self._done = True self._done = True
@ -181,9 +188,12 @@ class ServerManagerApp:
self._prerun() self._prerun()
# Print basic usage info for interactive mode. # Print basic usage info for interactive mode.
print(f"{Clr.CYN}Interactive mode enabled; use the 'mgr' object" print(
f' to interact with the server.\n' f"{Clr.CYN}Interactive mode enabled; use the 'mgr' object"
f"Type 'help(mgr)' for more information.{Clr.RST}") f' to interact with the server.\n'
f"Type 'help(mgr)' for more information.{Clr.RST}",
file=sys.stderr,
flush=True)
context = {'__name__': '__console__', '__doc__': None, 'mgr': self} context = {'__name__': '__console__', '__doc__': None, 'mgr': self}
@ -200,8 +210,11 @@ class ServerManagerApp:
# left in limbo with our process thread still running. # left in limbo with our process thread still running.
pass pass
except BaseException as exc: except BaseException as exc:
print(f'{Clr.SRED}Unexpected interpreter exception:' print(
f' {exc} ({type(exc)}){Clr.RST}') f'{Clr.SRED}Unexpected interpreter exception:'
f' {exc} ({type(exc)}){Clr.RST}',
file=sys.stderr,
flush=True)
self._postrun() self._postrun()
@ -450,16 +463,23 @@ class ServerManagerApp:
if strict: if strict:
raise CleanError( raise CleanError(
f'Error loading config file:\n{exc}') from exc f'Error loading config file:\n{exc}') from exc
print(f'{Clr.RED}Error loading config file:\n{exc}.{Clr.RST}') print(f'{Clr.RED}Error loading config file:\n{exc}.{Clr.RST}',
file=sys.stderr,
flush=True)
if trynum == maxtries - 1: if trynum == maxtries - 1:
print(f'{Clr.RED}Max-tries reached; giving up.' print(
f' Existing config values will be used.{Clr.RST}') f'{Clr.RED}Max-tries reached; giving up.'
f' Existing config values will be used.{Clr.RST}',
file=sys.stderr,
flush=True)
break break
print( print(
f'{Clr.CYN}Please correct the error.' f'{Clr.CYN}Please correct the error.'
f' Will re-attempt load in {retry_seconds}' f' Will re-attempt load in {retry_seconds}'
f' seconds. (attempt {trynum+1} of {maxtries-1}).{Clr.RST}' f' seconds. (attempt {trynum+1} of'
) f' {maxtries-1}).{Clr.RST}',
file=sys.stderr,
flush=True)
time.sleep(1) time.sleep(1)
@ -481,9 +501,12 @@ class ServerManagerApp:
# missing. # missing.
if not self._user_provided_config_path: if not self._user_provided_config_path:
if print_confirmation: if print_confirmation:
print(f'{Clr.YLW}Default config file not found' print(
f' (\'{self._config_path}\'); using default' f'{Clr.YLW}Default config file not found'
f' settings.{Clr.RST}') f' (\'{self._config_path}\'); using default'
f' settings.{Clr.RST}',
file=sys.stderr,
flush=True)
self._config_mtime = None self._config_mtime = None
self._last_config_mtime_check_time = time.time() self._last_config_mtime_check_time = time.time()
return ServerConfig() return ServerConfig()
@ -509,7 +532,9 @@ class ServerManagerApp:
out = ServerConfig() out = ServerConfig()
if print_confirmation: if print_confirmation:
print(f'{Clr.CYN}Valid server config file loaded.{Clr.RST}') print(f'{Clr.CYN}Valid server config file loaded.{Clr.RST}',
file=sys.stderr,
flush=True)
return out return out
def _enable_tab_completion(self, locs: Dict) -> None: def _enable_tab_completion(self, locs: Dict) -> None:
@ -552,7 +577,9 @@ class ServerManagerApp:
# slight behavior tweaks. Hmm; should this be an argument instead? # slight behavior tweaks. Hmm; should this be an argument instead?
os.environ['BA_SERVER_WRAPPER_MANAGED'] = '1' os.environ['BA_SERVER_WRAPPER_MANAGED'] = '1'
print(f'{Clr.CYN}Launching server subprocess...{Clr.RST}') print(f'{Clr.CYN}Launching server subprocess...{Clr.RST}',
file=sys.stderr,
flush=True)
binary_name = ('ballisticacore_headless.exe' binary_name = ('ballisticacore_headless.exe'
if os.name == 'nt' else './ballisticacore_headless') if os.name == 'nt' else './ballisticacore_headless')
assert self._ba_root_path is not None assert self._ba_root_path is not None
@ -663,7 +690,9 @@ class ServerManagerApp:
# alive. # alive.
if (self._subprocess_force_kill_time is not None if (self._subprocess_force_kill_time is not None
and time.time() > self._subprocess_force_kill_time): and time.time() > self._subprocess_force_kill_time):
print(f'{Clr.CYN}Force-killing subprocess...{Clr.RST}') print(f'{Clr.CYN}Force-killing subprocess...{Clr.RST}',
file=sys.stderr,
flush=True)
break break
# Watch for the server process exiting.. # Watch for the server process exiting..
@ -679,8 +708,11 @@ class ServerManagerApp:
self._should_report_subprocess_error = True self._should_report_subprocess_error = True
clr = Clr.CYN if code == 0 else Clr.RED clr = Clr.CYN if code == 0 else Clr.RED
print(f'{clr}Server subprocess exited' print(
f' with code {code}.{Clr.RST}') f'{clr}Server subprocess exited'
f' with code {code}.{Clr.RST}',
file=sys.stderr,
flush=True)
self._reset_subprocess_vars() self._reset_subprocess_vars()
# Avoid super fast death loops. # Avoid super fast death loops.
@ -709,8 +741,11 @@ class ServerManagerApp:
else: else:
mtime = None mtime = None
if mtime != self._config_mtime: if mtime != self._config_mtime:
print(f'{Clr.CYN}Config-file change detected;' print(
f' requesting immediate restart.{Clr.RST}') f'{Clr.CYN}Config-file change detected;'
f' requesting immediate restart.{Clr.RST}',
file=sys.stderr,
flush=True)
self.restart(immediate=True) self.restart(immediate=True)
self._subprocess_sent_config_auto_restart = True self._subprocess_sent_config_auto_restart = True
@ -724,10 +759,13 @@ class ServerManagerApp:
if (minutes_since_launch > clean_exit_minutes if (minutes_since_launch > clean_exit_minutes
and not self._subprocess_sent_clean_exit): and not self._subprocess_sent_clean_exit):
opname = 'restart' if self._auto_restart else 'shutdown' opname = 'restart' if self._auto_restart else 'shutdown'
print(f'{Clr.CYN}clean_exit_minutes' print(
f' ({clean_exit_minutes})' f'{Clr.CYN}clean_exit_minutes'
f' elapsed; requesting soft' f' ({clean_exit_minutes})'
f' {opname}.{Clr.RST}') f' elapsed; requesting soft'
f' {opname}.{Clr.RST}',
file=sys.stderr,
flush=True)
if self._auto_restart: if self._auto_restart:
self.restart(immediate=False) self.restart(immediate=False)
else: else:
@ -744,10 +782,13 @@ class ServerManagerApp:
if (minutes_since_launch > unclean_exit_minutes if (minutes_since_launch > unclean_exit_minutes
and not self._subprocess_sent_unclean_exit): and not self._subprocess_sent_unclean_exit):
opname = 'restart' if self._auto_restart else 'shutdown' opname = 'restart' if self._auto_restart else 'shutdown'
print(f'{Clr.CYN}unclean_exit_minutes' print(
f' ({unclean_exit_minutes})' f'{Clr.CYN}unclean_exit_minutes'
f' elapsed; requesting immediate' f' ({unclean_exit_minutes})'
f' {opname}.{Clr.RST}') f' elapsed; requesting immediate'
f' {opname}.{Clr.RST}',
file=sys.stderr,
flush=True)
if self._auto_restart: if self._auto_restart:
self.restart(immediate=True) self.restart(immediate=True)
else: else:
@ -768,7 +809,9 @@ class ServerManagerApp:
if self._subprocess is None: if self._subprocess is None:
return return
print(f'{Clr.CYN}Stopping subprocess...{Clr.RST}') print(f'{Clr.CYN}Stopping subprocess...{Clr.RST}',
file=sys.stderr,
flush=True)
# First, ask it nicely to die and give it a moment. # First, ask it nicely to die and give it a moment.
# If that doesn't work, bring down the hammer. # If that doesn't work, bring down the hammer.
@ -778,7 +821,9 @@ class ServerManagerApp:
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
self._subprocess.kill() self._subprocess.kill()
self._reset_subprocess_vars() self._reset_subprocess_vars()
print(f'{Clr.CYN}Subprocess stopped.{Clr.RST}') print(f'{Clr.CYN}Subprocess stopped.{Clr.RST}',
file=sys.stderr,
flush=True)
def main() -> None: def main() -> None:

View File

@ -1,5 +1,5 @@
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND --> <!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
<h4><em>last updated on 2021-02-25 for Ballistica version 1.6.0 build 20308</em></h4> <h4><em>last updated on 2021-02-25 for Ballistica version 1.6.0 build 20309</em></h4>
<p>This page documents the Python classes and functions in the 'ba' module, <p>This page documents the Python classes and functions in the 'ba' module,
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p> which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
<hr> <hr>

View File

@ -128,11 +128,8 @@ void App::ShutdownComplete() {
} }
void App::RunEvents() { void App::RunEvents() {
if (!HeadlessMode()) { // there's probably a better place for this...
// there's probably a better place for this... stress_test_->Update();
// UpdateStressTesting();
stress_test_->Update();
}
// Give platforms a chance to pump/handle their own events. // Give platforms a chance to pump/handle their own events.
// FIXME: now that we have app class overrides, platform should really // FIXME: now that we have app class overrides, platform should really

View File

@ -10,10 +10,13 @@ namespace ballistica {
// We could technically use the vanilla App class here since we're not // We could technically use the vanilla App class here since we're not
// changing anything. // changing anything.
HeadlessApp::HeadlessApp(Thread* thread) : App(thread) { HeadlessApp::HeadlessApp(Thread* thread) : App(thread) {
// NewThreadTimer(10, true, NewLambdaRunnable([this] { // Handle a few misc things like stress-test updates.
// assert(g_app); // (SDL builds set up a similar timer so we need to also).
// g_app->RunEvents(); // This can probably go away at some point.
// })); NewThreadTimer(10, true, NewLambdaRunnable([this] {
assert(g_app);
g_app->RunEvents();
}));
} }
} // namespace ballistica } // namespace ballistica

View File

@ -21,7 +21,7 @@
namespace ballistica { namespace ballistica {
// These are set automatically via script; don't change here. // These are set automatically via script; don't change here.
const int kAppBuildNumber = 20308; const int kAppBuildNumber = 20310;
const char* kAppVersion = "1.6.0"; const char* kAppVersion = "1.6.0";
// Our standalone globals. // Our standalone globals.

View File

@ -111,6 +111,9 @@ class ServerConfig:
# auto-restart is enabled (the default). # auto-restart is enabled (the default).
idle_exit_minutes: Optional[float] = None idle_exit_minutes: Optional[float] = None
# (internal) stress-testing mode.
stress_test_players: Optional[int] = None
# NOTE: as much as possible, communication from the server-manager to the # NOTE: as much as possible, communication from the server-manager to the
# child-process should go through these and not ad-hoc Python string commands # child-process should go through these and not ad-hoc Python string commands

View File

@ -650,8 +650,11 @@ def _get_server_config_template_yaml(projroot: str) -> str:
import yaml import yaml
lines_in = _get_server_config_raw_contents(projroot).splitlines() lines_in = _get_server_config_raw_contents(projroot).splitlines()
lines_out: List[str] = [] lines_out: List[str] = []
ignore_vars = {'stress_test_players'}
for line in lines_in: for line in lines_in:
if line != '' and not line.startswith('#'): if (line != '' and not line.startswith('#')
and not any(line.startswith(f'{var}:')
for var in ignore_vars)):
vname, _vtype, veq, vval_raw = line.split() vname, _vtype, veq, vval_raw = line.split()
assert vname.endswith(':') assert vname.endswith(':')
vname = vname[:-1] vname = vname[:-1]
@ -685,7 +688,8 @@ def _get_server_config_template_yaml(projroot: str) -> str:
else: else:
# Convert comments referring to python bools to yaml bools. # Convert comments referring to python bools to yaml bools.
line = line.replace('True', 'true').replace('False', 'false') line = line.replace('True', 'true').replace('False', 'false')
lines_out.append(line) if '(internal)' not in line:
lines_out.append(line)
return '\n'.join(lines_out) return '\n'.join(lines_out)