fix(updates): resolve component update hang and multiple page reload loop
- action.uc: sweep stuck flock 1000 processes before tachyon restart, bound service restart with 25s timeout, and prevent worker lockup - shell/index.ts: add 15-minute general hard timeout for non-Tachyon components to prevent infinite modal spin; allow same-version confirmation for both install and reinstall - package.uc: remove disruptive uhttpd restart from luci_postinst to prevent active socket drops - ui.uc: refresh stale PID state before checking value.running in action_ack so dead jobs can always be acknowledged - initController.ts & sessionJobs.ts: persist handled job IDs across reloads in sessionStorage, eliminate redundant modal popups on page reload, and guard against concurrent reloads with safeReloadPage - renderUpdateProgressModal.ts: record active job before reload and poll readiness with fast health check instead of blind 5s freeze
This commit is contained in:
@@ -447,6 +447,42 @@ function command_output_from_args(args) {
|
||||
return command_output(command_from_args(args) + " 2>/dev/null");
|
||||
}
|
||||
|
||||
let timeout_prefix_cache = null;
|
||||
|
||||
function timeout_prefix() {
|
||||
if (timeout_prefix_cache != null)
|
||||
return timeout_prefix_cache;
|
||||
|
||||
if (command_status("timeout 1 /bin/true >/dev/null 2>&1") == 0)
|
||||
timeout_prefix_cache = [ "timeout" ];
|
||||
else if (command_status("timeout -t 1 /bin/true >/dev/null 2>&1") == 0)
|
||||
timeout_prefix_cache = [ "timeout", "-t" ];
|
||||
else
|
||||
timeout_prefix_cache = [];
|
||||
|
||||
return timeout_prefix_cache;
|
||||
}
|
||||
|
||||
function bounded_command(command, seconds) {
|
||||
seconds = as_string(seconds || "30");
|
||||
let prefix = timeout_prefix();
|
||||
if (length(prefix) == 0)
|
||||
return as_string(command);
|
||||
|
||||
return join(" ", prefix) + " " + seconds + " " + as_string(command);
|
||||
}
|
||||
|
||||
function kill_matching_command(grep_args) {
|
||||
return "__anc=\" \"; __p=$$; " +
|
||||
"while [ -n \"$__p\" ] && [ \"$__p\" -gt 1 ] 2>/dev/null; do " +
|
||||
"__anc=\"$__anc$__p \"; " +
|
||||
"__p=$(awk '{ sub(/.*\\) /, \"\"); print $2 }' \"/proc/$__p/stat\" 2>/dev/null); " +
|
||||
"done; " +
|
||||
"ps 2>/dev/null | grep " + grep_args + " | grep -v grep | grep -v -E 'action[.]uc|updates[.]uc' | awk '{print $1}' | " +
|
||||
"while read _pid; do case \"$__anc\" in *\" $_pid \"*) continue;; esac; " +
|
||||
"kill -9 \"$_pid\" 2>/dev/null; done; true";
|
||||
}
|
||||
|
||||
function ensure_dir(path) {
|
||||
path = as_string(path);
|
||||
if (path == "") return false;
|
||||
@@ -559,5 +595,8 @@ return {
|
||||
write_file,
|
||||
file_exists,
|
||||
parent_dir,
|
||||
get_mixed_port
|
||||
get_mixed_port,
|
||||
timeout_prefix,
|
||||
bounded_command,
|
||||
kill_matching_command
|
||||
};
|
||||
Reference in New Issue
Block a user