fixed server_stopped file check
This commit is contained in:
parent
a1f1f8529f
commit
1d04e2a4e8
2 changed files with 32 additions and 48 deletions
|
|
@ -502,7 +502,7 @@ sub create_screen_cmd
|
||||||
|
|
||||||
sub create_screen_cmd_loop
|
sub create_screen_cmd_loop
|
||||||
{
|
{
|
||||||
my ($screen_id, $exec_cmd, $priority, $affinity, $envVars) = @_;
|
my ($screen_id, $exec_cmd, $priority, $affinity, $envVars, $status_hint_file) = @_;
|
||||||
my $server_start_batfile = "_serverStart.bat";
|
my $server_start_batfile = "_serverStart.bat";
|
||||||
|
|
||||||
$exec_cmd = replace_OGP_Env_Vars($screen_id, "", "", $exec_cmd);
|
$exec_cmd = replace_OGP_Env_Vars($screen_id, "", "", $exec_cmd);
|
||||||
|
|
@ -517,6 +517,7 @@ sub create_screen_cmd_loop
|
||||||
if(defined $envVars && $envVars ne ""){
|
if(defined $envVars && $envVars ne ""){
|
||||||
$batch_server_command .= $envVars;
|
$batch_server_command .= $envVars;
|
||||||
}# lines 500-515, inside sub create_screen_cmd_loop
|
}# lines 500-515, inside sub create_screen_cmd_loop
|
||||||
|
$status_hint_file = "" unless(defined($status_hint_file));
|
||||||
$batch_server_command .= "set STARTTIME=%TIME: =0%" . "\r\n"
|
$batch_server_command .= "set STARTTIME=%TIME: =0%" . "\r\n"
|
||||||
. "\@echo off\r\n"
|
. "\@echo off\r\n"
|
||||||
. "if exist \"_alsoRun.bat\" call \"_alsoRun.bat\"\r\n"
|
. "if exist \"_alsoRun.bat\" call \"_alsoRun.bat\"\r\n"
|
||||||
|
|
@ -529,7 +530,7 @@ $batch_server_command .= "set STARTTIME=%TIME: =0%" . "\r\n"
|
||||||
. "set hour=%hh:~1%\r\n"
|
. "set hour=%hh:~1%\r\n"
|
||||||
. "set minute=%mm:~1%\r\n"
|
. "set minute=%mm:~1%\r\n"
|
||||||
. "set second=%ss:~1%\r\n"
|
. "set second=%ss:~1%\r\n"
|
||||||
. "if exist SERVER_STOPPED exit\r\n"
|
. "if exist \"$status_hint_file\" findstr /I /R /C:\"^[0-9][0-9]*,STOPPING$\" /C:\"^[0-9][0-9]*,STOPPED$\" \"$status_hint_file\" >nul && exit\r\n"
|
||||||
. "IF \"%hour%\" == \"00\" IF \"%minute%\" == \"00\" IF %second% lss 60 exit\r\n"
|
. "IF \"%hour%\" == \"00\" IF \"%minute%\" == \"00\" IF %second% lss 60 exit\r\n"
|
||||||
. "timeout /t 30 /nobreak >nul\r\n"
|
. "timeout /t 30 /nobreak >nul\r\n"
|
||||||
. "goto TOP\r\n";
|
. "goto TOP\r\n";
|
||||||
|
|
@ -1052,9 +1053,8 @@ sub server_status_without_decrypt
|
||||||
|
|
||||||
if(!$process_running && ((!PORT_VALIDATION_ENABLED && $game_port_listening) || ($expected_count > 0 && $listening_count > 0)))
|
if(!$process_running && ((!PORT_VALIDATION_ENABLED && $game_port_listening) || ($expected_count > 0 && $listening_count > 0)))
|
||||||
{
|
{
|
||||||
$status = "ONLINE";
|
$status = "WARNING";
|
||||||
$ready = 1;
|
$status_state = "Warning";
|
||||||
$status_state = $missing_count == 0 ? "Running" : "Warning";
|
|
||||||
$last_error = "Required port is listening but the managed screen session is not running.";
|
$last_error = "Required port is listening but the managed screen session is not running.";
|
||||||
}
|
}
|
||||||
elsif($process_running)
|
elsif($process_running)
|
||||||
|
|
@ -1081,7 +1081,7 @@ sub server_status_without_decrypt
|
||||||
elsif($effective_hint eq "STOPPING")
|
elsif($effective_hint eq "STOPPING")
|
||||||
{
|
{
|
||||||
$status = "STOPPING";
|
$status = "STOPPING";
|
||||||
$status_state = "Starting";
|
$status_state = "Stopping";
|
||||||
}
|
}
|
||||||
elsif($hint_timestamp > 0 && (time() - $hint_timestamp) > $startup_timeout)
|
elsif($hint_timestamp > 0 && (time() - $hint_timestamp) > $startup_timeout)
|
||||||
{
|
{
|
||||||
|
|
@ -1127,6 +1127,7 @@ sub server_status_without_decrypt
|
||||||
pid => $game_pid ne "" ? $game_pid : ($windows_pid ne "" ? $windows_pid : $screen_pid),
|
pid => $game_pid ne "" ? $game_pid : ($windows_pid ne "" ? $windows_pid : $screen_pid),
|
||||||
screen_pid => $screen_pid,
|
screen_pid => $screen_pid,
|
||||||
windows_pid => $windows_pid,
|
windows_pid => $windows_pid,
|
||||||
|
linux_pid => "",
|
||||||
session_name => $screen_id,
|
session_name => $screen_id,
|
||||||
ip => $server_ip,
|
ip => $server_ip,
|
||||||
port => $server_port,
|
port => $server_port,
|
||||||
|
|
@ -1137,17 +1138,6 @@ sub server_status_without_decrypt
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
# Delete Server Stopped Status File:
|
|
||||||
sub deleteStoppedStatFile
|
|
||||||
{
|
|
||||||
my ($home_path) = @_;
|
|
||||||
my $server_stop_status_file = Path::Class::File->new($home_path, "SERVER_STOPPED");
|
|
||||||
if(-e $server_stop_status_file)
|
|
||||||
{
|
|
||||||
unlink $server_stop_status_file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Universal startup function
|
# Universal startup function
|
||||||
sub universal_start
|
sub universal_start
|
||||||
{
|
{
|
||||||
|
|
@ -1223,6 +1213,9 @@ sub universal_start_without_decrypt
|
||||||
}
|
}
|
||||||
|
|
||||||
my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
|
my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
|
||||||
|
my $status_hint_file = get_status_hint_path($home_id);
|
||||||
|
my $status_hint_file_windows = clean(`cygpath -wa $status_hint_file`);
|
||||||
|
chomp($status_hint_file_windows);
|
||||||
|
|
||||||
# Replace any OGP variables
|
# Replace any OGP variables
|
||||||
$startup_cmd = replace_OGP_Env_Vars($screen_id, $home_id, $home_path, $startup_cmd, $game_key);
|
$startup_cmd = replace_OGP_Env_Vars($screen_id, $home_id, $home_path, $startup_cmd, $game_key);
|
||||||
|
|
@ -1288,8 +1281,7 @@ sub universal_start_without_decrypt
|
||||||
if($file_extension eq ".jar")
|
if($file_extension eq ".jar")
|
||||||
{
|
{
|
||||||
if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){
|
if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){
|
||||||
deleteStoppedStatFile($home_path);
|
$cli_bin = create_screen_cmd_loop($screen_id, "$startup_cmd", $priority, $affinity, undef, $status_hint_file_windows);
|
||||||
$cli_bin = create_screen_cmd_loop($screen_id, "$startup_cmd", $priority, $affinity);
|
|
||||||
}else{
|
}else{
|
||||||
$cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT $startup_cmd");
|
$cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT $startup_cmd");
|
||||||
}
|
}
|
||||||
|
|
@ -1300,8 +1292,7 @@ sub universal_start_without_decrypt
|
||||||
# but it can be a good way to improve the server startup. To be able to use
|
# but it can be a good way to improve the server startup. To be able to use
|
||||||
# sh/bash scripts as server executable I added this piece to the agent:
|
# sh/bash scripts as server executable I added this piece to the agent:
|
||||||
if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){
|
if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){
|
||||||
deleteStoppedStatFile($home_path);
|
$cli_bin = create_screen_cmd_loop($screen_id, "bash $game_binary_dir/$server_exe $startup_cmd", $priority, $affinity, undef, $status_hint_file_windows);
|
||||||
$cli_bin = create_screen_cmd_loop($screen_id, "bash $game_binary_dir/$server_exe $startup_cmd", $priority, $affinity);
|
|
||||||
}else{
|
}else{
|
||||||
$cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT bash $game_binary_dir/$server_exe $startup_cmd");
|
$cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT bash $game_binary_dir/$server_exe $startup_cmd");
|
||||||
}
|
}
|
||||||
|
|
@ -1309,8 +1300,7 @@ sub universal_start_without_decrypt
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){
|
if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){
|
||||||
deleteStoppedStatFile($home_path);
|
$cli_bin = create_screen_cmd_loop($screen_id, "$win_game_binary_dir\\$server_exe $startup_cmd", $priority, $affinity, undef, $status_hint_file_windows);
|
||||||
$cli_bin = create_screen_cmd_loop($screen_id, "$win_game_binary_dir\\$server_exe $startup_cmd", $priority, $affinity);
|
|
||||||
}else{
|
}else{
|
||||||
# Below lines should only be used for launching non-auto restart game servers
|
# Below lines should only be used for launching non-auto restart game servers
|
||||||
$win_game_binary_dir =~ s/\\/\\\\/g;
|
$win_game_binary_dir =~ s/\\/\\\\/g;
|
||||||
|
|
@ -1634,21 +1624,6 @@ sub stop_server_without_decrypt
|
||||||
or logger "Cannot remove the startup flag file $startup_file $!";
|
or logger "Cannot remove the startup flag file $startup_file $!";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create file indicator that the game server has been stopped if defined
|
|
||||||
if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){
|
|
||||||
|
|
||||||
# Get current directory and chdir into the game's home dir
|
|
||||||
my $curDir = getcwd();
|
|
||||||
chdir $home_path;
|
|
||||||
|
|
||||||
# Create stopped indicator file used by autorestart of OGP if server crashes
|
|
||||||
open(STOPFILE, '>', "SERVER_STOPPED");
|
|
||||||
close(STOPFILE);
|
|
||||||
|
|
||||||
# Return to original directory
|
|
||||||
chdir $curDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
|
my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
|
||||||
my $screen_pid = get_screen_pid_without_decrypt($home_id);
|
my $screen_pid = get_screen_pid_without_decrypt($home_id);
|
||||||
my $pid_meta = read_pid_metadata($home_id);
|
my $pid_meta = read_pid_metadata($home_id);
|
||||||
|
|
@ -1675,15 +1650,16 @@ sub stop_server_without_decrypt
|
||||||
system("cmd /C taskkill /F /T /PID $port_pid >nul 2>&1");
|
system("cmd /C taskkill /F /T /PID $port_pid >nul 2>&1");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $stop_result = verify_server_stopped_without_decrypt($home_id, $server_ip, $server_port);
|
my $stop_result = verify_runtime_stop_complete_without_decrypt($home_id, $server_ip, $server_port);
|
||||||
if($stop_result == 0)
|
if($stop_result == 0)
|
||||||
{
|
{
|
||||||
clear_pid_metadata($home_id);
|
clear_pid_metadata($home_id);
|
||||||
|
write_status_hint($home_id, "STOPPED");
|
||||||
}
|
}
|
||||||
return $stop_result;
|
return $stop_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub verify_server_stopped_without_decrypt
|
sub verify_runtime_stop_complete_without_decrypt
|
||||||
{
|
{
|
||||||
my ($home_id, $server_ip, $server_port) = @_;
|
my ($home_id, $server_ip, $server_port) = @_;
|
||||||
my $pid_meta = read_pid_metadata($home_id);
|
my $pid_meta = read_pid_metadata($home_id);
|
||||||
|
|
@ -1694,7 +1670,11 @@ sub verify_server_stopped_without_decrypt
|
||||||
$pid_running = 1 if(defined($pid_meta->{windows_pid}) && $pid_meta->{windows_pid} =~ /^\d+$/ && is_pid_alive_without_decrypt($pid_meta->{windows_pid}) == 1);
|
$pid_running = 1 if(defined($pid_meta->{windows_pid}) && $pid_meta->{windows_pid} =~ /^\d+$/ && is_pid_alive_without_decrypt($pid_meta->{windows_pid}) == 1);
|
||||||
$pid_running = 1 if(!$pid_running && defined($pid_meta->{game_pid}) && $pid_meta->{game_pid} =~ /^\d+$/ && is_pid_alive_without_decrypt($pid_meta->{game_pid}) == 1);
|
$pid_running = 1 if(!$pid_running && defined($pid_meta->{game_pid}) && $pid_meta->{game_pid} =~ /^\d+$/ && is_pid_alive_without_decrypt($pid_meta->{game_pid}) == 1);
|
||||||
my $port_listening = is_port_listening_without_decrypt($server_ip, $server_port);
|
my $port_listening = is_port_listening_without_decrypt($server_ip, $server_port);
|
||||||
return 0 if(!$session_running && !$pid_running && !$port_listening);
|
if(!$session_running && !$pid_running && !$port_listening)
|
||||||
|
{
|
||||||
|
write_status_hint($home_id, "STOPPED");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
sleep 2;
|
sleep 2;
|
||||||
}
|
}
|
||||||
my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
|
my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
|
||||||
|
|
@ -1713,6 +1693,7 @@ sub verify_server_stopped_without_decrypt
|
||||||
logger "Server $server_ip:$server_port is still running or listening after stop escalation.";
|
logger "Server $server_ip:$server_port is still running or listening after stop escalation.";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
write_status_hint($home_id, "STOPPED");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3001,7 +2982,7 @@ sub restart_server_without_decrypt
|
||||||
{
|
{
|
||||||
logger "Waiting 60 seconds before starting the server again.";
|
logger "Waiting 60 seconds before starting the server again.";
|
||||||
sleep 60;
|
sleep 60;
|
||||||
if (verify_server_stopped_without_decrypt($home_id, $server_ip, $server_port) != 0)
|
if (verify_runtime_stop_complete_without_decrypt($home_id, $server_ip, $server_port) != 0)
|
||||||
{
|
{
|
||||||
logger "Restart cancelled: previous instance is still active after stop wait window.";
|
logger "Restart cancelled: previous instance is still active after stop wait window.";
|
||||||
return -2;
|
return -2;
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,15 @@ Tracked fields include PID/session information used to stop the right process re
|
||||||
When stop is requested, the agent now:
|
When stop is requested, the agent now:
|
||||||
|
|
||||||
1. marks status hint as `STOPPING`
|
1. marks status hint as `STOPPING`
|
||||||
2. creates `SERVER_STOPPED` marker for autorestart handling
|
2. removes startup flag for `<ip>-<port>`
|
||||||
3. removes startup flag for `<ip>-<port>`
|
3. kills tracked PIDs (`screen_pid`, `windows_pid`, `game_pid`) if present
|
||||||
4. kills tracked PIDs (`screen_pid`, `windows_pid`, `game_pid`) if present
|
4. kills managed screen session
|
||||||
5. kills managed screen session
|
5. checks if the game port is still listening and kills the owning PID
|
||||||
6. checks if the game port is still listening and kills the owning PID
|
6. verifies stop success (no managed session, no tracked running PID, no listening game port)
|
||||||
7. verifies stop success (no managed session, no tracked running PID, no listening game port)
|
7. writes status hint `STOPPED` only after verification passes
|
||||||
|
|
||||||
|
The agent no longer creates or reads `SERVER_STOPPED`/`Server_Stopped` marker files for lifecycle control.
|
||||||
|
Autorestart loop control now uses agent-owned runtime status hints (`STARTING`/`STOPPING`/`STOPPED`) instead of game-home marker files.
|
||||||
|
|
||||||
## Restart behavior
|
## Restart behavior
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue