fix(join): increase join_world timeout, log dedicated server stdout/stderr, null check multiplayer
checkpoint / checkpoint (push) Successful in 5m49s
checkpoint / checkpoint (push) Successful in 5m49s
This commit is contained in:
@@ -50,6 +50,7 @@ class _WorldServer:
|
|||||||
proc: subprocess.Popen
|
proc: subprocess.Popen
|
||||||
status_path: Path
|
status_path: Path
|
||||||
token: str
|
token: str
|
||||||
|
log_path: Path | None = None
|
||||||
started_at: float = field(default_factory=time.time)
|
started_at: float = field(default_factory=time.time)
|
||||||
last_join: float = field(default_factory=time.time)
|
last_join: float = field(default_factory=time.time)
|
||||||
|
|
||||||
@@ -150,6 +151,7 @@ class GameServerSupervisor:
|
|||||||
token = secrets.token_urlsafe(32)
|
token = secrets.token_urlsafe(32)
|
||||||
status_path = self._runtime_dir / f"world_{world_id}_{port}.json"
|
status_path = self._runtime_dir / f"world_{world_id}_{port}.json"
|
||||||
status_path.unlink(missing_ok=True)
|
status_path.unlink(missing_ok=True)
|
||||||
|
log_path = self._runtime_dir / f"world_{world_id}_{port}.log"
|
||||||
cmd = [
|
cmd = [
|
||||||
settings.GODOT_BIN, "--headless",
|
settings.GODOT_BIN, "--headless",
|
||||||
"--path", settings.GAME_PROJECT_DIR,
|
"--path", settings.GAME_PROJECT_DIR,
|
||||||
@@ -160,9 +162,10 @@ class GameServerSupervisor:
|
|||||||
"--api-url", settings.GAME_SERVER_INTERNAL_API_URL,
|
"--api-url", settings.GAME_SERVER_INTERNAL_API_URL,
|
||||||
"--server-token", token,
|
"--server-token", token,
|
||||||
]
|
]
|
||||||
proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
log_file = open(log_path, "w")
|
||||||
|
proc = subprocess.Popen(cmd, stdout=log_file, stderr=subprocess.STDOUT)
|
||||||
return _WorldServer(
|
return _WorldServer(
|
||||||
world_id=world_id, port=port, proc=proc, status_path=status_path, token=token
|
world_id=world_id, port=port, proc=proc, status_path=status_path, token=token, log_path=log_path
|
||||||
)
|
)
|
||||||
|
|
||||||
def _free_port(self) -> int:
|
def _free_port(self) -> int:
|
||||||
@@ -199,13 +202,27 @@ class GameServerSupervisor:
|
|||||||
if srv.is_ready():
|
if srv.is_ready():
|
||||||
return
|
return
|
||||||
if not srv.alive():
|
if not srv.alive():
|
||||||
|
log_snippet = ""
|
||||||
|
if srv.log_path and srv.log_path.exists():
|
||||||
|
try:
|
||||||
|
log_snippet = srv.log_path.read_text()[-500:]
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
raise TimeoutError(
|
raise TimeoutError(
|
||||||
f"server process for world {srv.world_id} exited before becoming ready"
|
f"server process for world {srv.world_id} exited before becoming ready"
|
||||||
|
+ (f": {log_snippet}" if log_snippet else "")
|
||||||
)
|
)
|
||||||
await asyncio.sleep(0.25)
|
await asyncio.sleep(0.25)
|
||||||
|
log_snippet = ""
|
||||||
|
if srv.log_path and srv.log_path.exists():
|
||||||
|
try:
|
||||||
|
log_snippet = srv.log_path.read_text()[-500:]
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
raise TimeoutError(
|
raise TimeoutError(
|
||||||
f"server for world {srv.world_id} did not report ready within "
|
f"server for world {srv.world_id} did not report ready within "
|
||||||
f"{settings.GAME_SERVER_READY_TIMEOUT_SECONDS}s"
|
f"{settings.GAME_SERVER_READY_TIMEOUT_SECONDS}s"
|
||||||
|
+ (f": {log_snippet}" if log_snippet else "")
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _reap_loop(self) -> None:
|
async def _reap_loop(self) -> None:
|
||||||
|
|||||||
@@ -139,10 +139,11 @@ func request(
|
|||||||
body: String = "",
|
body: String = "",
|
||||||
content_type: String = "application/json",
|
content_type: String = "application/json",
|
||||||
require_auth: bool = false,
|
require_auth: bool = false,
|
||||||
custom_headers: PackedStringArray = PackedStringArray()
|
custom_headers: PackedStringArray = PackedStringArray(),
|
||||||
|
custom_timeout: float = 0.0
|
||||||
) -> Dictionary:
|
) -> Dictionary:
|
||||||
var http := HTTPRequest.new()
|
var http := HTTPRequest.new()
|
||||||
http.timeout = timeout_seconds
|
http.timeout = custom_timeout if custom_timeout > 0.0 else timeout_seconds
|
||||||
http.max_redirects = 8
|
http.max_redirects = 8
|
||||||
http.accept_gzip = true
|
http.accept_gzip = true
|
||||||
add_child(http)
|
add_child(http)
|
||||||
@@ -268,7 +269,7 @@ func get_avatar_loadout() -> Dictionary:
|
|||||||
## its address. On success result.data is {"world_id", "host", "port"}.
|
## its address. On success result.data is {"world_id", "host", "port"}.
|
||||||
## 503 if this backend has no game-server orchestration.
|
## 503 if this backend has no game-server orchestration.
|
||||||
func join_world(world_id: int) -> Dictionary:
|
func join_world(world_id: int) -> Dictionary:
|
||||||
return await request(HTTPClient.METHOD_POST, "/api/worlds/%d/join" % world_id, "", "application/json", true)
|
return await request(HTTPClient.METHOD_POST, "/api/worlds/%d/join" % world_id, "", "application/json", true, PackedStringArray(), 25.0)
|
||||||
|
|
||||||
|
|
||||||
## Save (replace) the current user's avatar loadout (requires auth).
|
## Save (replace) the current user's avatar loadout (requires auth).
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ func disconnect_from_server() -> void:
|
|||||||
peer.close()
|
peer.close()
|
||||||
if _server_root and is_instance_valid(_server_root):
|
if _server_root and is_instance_valid(_server_root):
|
||||||
_server_root.queue_free()
|
_server_root.queue_free()
|
||||||
multiplayer.multiplayer_peer = null
|
if multiplayer:
|
||||||
|
multiplayer.multiplayer_peer = null
|
||||||
_prediction_buffer.clear()
|
_prediction_buffer.clear()
|
||||||
_remote_states.clear()
|
_remote_states.clear()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user