@myassis/gateway 1.0.46 → 1.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/services/ServiceManager.js +74 -12
- package/package.json +1 -1
|
@@ -103,11 +103,35 @@ function getStoredPid() {
|
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
105
|
* 停止 Gateway 用户进程(优雅终止)
|
|
106
|
+
*
|
|
107
|
+
* 注意:当 pid 指向当前进程自己时,绝不能使用 process.kill(pid)。
|
|
108
|
+
* - Windows 上 Node 的 process.kill 等同 TerminateProcess,无清理机会,
|
|
109
|
+
* server.close() / WebSocket / 文件句柄都不会被释放,会导致后续 exe 解锁超时。
|
|
110
|
+
* - 因此自杀场景改走 process.emit('SIGTERM'),复用 main.ts 已注册的优雅关闭逻辑,
|
|
111
|
+
* 并在响应返回后异步退出,避免 HTTP 调用方读不到结果。
|
|
106
112
|
*/
|
|
107
113
|
async function stopGatewayProcess() {
|
|
108
114
|
const pid = getStoredPid();
|
|
109
115
|
if (!pid)
|
|
110
116
|
return;
|
|
117
|
+
// —— 场景 1:要停的就是自己 —— 走优雅退出
|
|
118
|
+
if (pid === process.pid) {
|
|
119
|
+
try {
|
|
120
|
+
fs_1.default.unlinkSync(GATEWAY_PID_FILE);
|
|
121
|
+
}
|
|
122
|
+
catch { /* ignore */ }
|
|
123
|
+
// 异步触发,确保当前调用栈(含 HTTP 响应)有机会先返回
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
try {
|
|
126
|
+
process.emit('SIGTERM');
|
|
127
|
+
}
|
|
128
|
+
catch { /* ignore */ }
|
|
129
|
+
// 兜底:5s 内 SIGTERM handler 没把进程关掉,再强退
|
|
130
|
+
setTimeout(() => process.exit(0), 5000).unref();
|
|
131
|
+
}, 100).unref();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// —— 场景 2:停的是别人(孤儿进程 / 旧实例)—— 才真正发信号
|
|
111
135
|
try {
|
|
112
136
|
process.kill(pid, 'SIGTERM');
|
|
113
137
|
await new Promise(r => setTimeout(r, 2000));
|
|
@@ -521,20 +545,40 @@ async function updateService() {
|
|
|
521
545
|
`if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }`,
|
|
522
546
|
`function Write-UpdateLog { param([string]$Message) Add-Content -Path $logPath -Encoding UTF8 -Value \"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') $Message\" }`,
|
|
523
547
|
`function Stop-GatewayProcess {`,
|
|
524
|
-
`
|
|
548
|
+
` $stoppedPids = @{}`,
|
|
549
|
+
` if (Test-Path $pidFile) {`,
|
|
550
|
+
` try {`,
|
|
551
|
+
` $pidValue = (Get-Content $pidFile -Raw).Trim()`,
|
|
552
|
+
` if ($pidValue) {`,
|
|
553
|
+
` $pidInt = [int]$pidValue`,
|
|
554
|
+
` Write-UpdateLog \"stopping gateway process by pid file pid=$pidInt\"`,
|
|
555
|
+
` try { Stop-Process -Id $pidInt -Force -ErrorAction Stop; $stoppedPids[$pidInt] = $true } catch { Write-UpdateLog \"stop-process by pid failed: $($_.Exception.Message)\" }`,
|
|
556
|
+
` }`,
|
|
557
|
+
` } catch { Write-UpdateLog \"read pid file error: $($_.Exception.Message)\" }`,
|
|
558
|
+
` Remove-Item $pidFile -Force -ErrorAction SilentlyContinue`,
|
|
559
|
+
` } else { Write-UpdateLog 'pid file not found, fallback to path match' }`,
|
|
525
560
|
` try {`,
|
|
526
|
-
` $
|
|
527
|
-
`
|
|
528
|
-
` $
|
|
529
|
-
`
|
|
530
|
-
`
|
|
561
|
+
` $targetFull = [System.IO.Path]::GetFullPath($currentExe)`,
|
|
562
|
+
` $targetName = [System.IO.Path]::GetFileNameWithoutExtension($currentExe)`,
|
|
563
|
+
` $procs = Get-Process -Name $targetName -ErrorAction SilentlyContinue`,
|
|
564
|
+
` foreach ($proc in $procs) {`,
|
|
565
|
+
` try {`,
|
|
566
|
+
` $procPath = $null`,
|
|
567
|
+
` try { $procPath = $proc.Path } catch { $procPath = $null }`,
|
|
568
|
+
` if ($procPath -and ([System.IO.Path]::GetFullPath($procPath) -ieq $targetFull)) {`,
|
|
569
|
+
` Write-UpdateLog \"stopping gateway process by path pid=$($proc.Id), path=$procPath\"`,
|
|
570
|
+
` try { Stop-Process -Id $proc.Id -Force -ErrorAction Stop; $stoppedPids[$proc.Id] = $true } catch { Write-UpdateLog \"stop-process by path failed pid=$($proc.Id): $($_.Exception.Message)\" }`,
|
|
571
|
+
` }`,
|
|
572
|
+
` } catch { Write-UpdateLog \"inspect process failed pid=$($proc.Id): $($_.Exception.Message)\" }`,
|
|
573
|
+
` }`,
|
|
574
|
+
` } catch { Write-UpdateLog \"enumerate processes error: $($_.Exception.Message)\" }`,
|
|
575
|
+
` foreach ($spid in $stoppedPids.Keys) {`,
|
|
531
576
|
` for ($w = 0; $w -lt 30; $w++) {`,
|
|
532
|
-
` $p = Get-Process -Id $
|
|
577
|
+
` $p = Get-Process -Id $spid -ErrorAction SilentlyContinue`,
|
|
533
578
|
` if (-not $p) { break }`,
|
|
534
579
|
` Start-Sleep -Milliseconds 500`,
|
|
535
580
|
` }`,
|
|
536
|
-
`
|
|
537
|
-
` } catch { Write-UpdateLog \"stop gateway error: $($_.Exception.Message)\" }`,
|
|
581
|
+
` }`,
|
|
538
582
|
`}`,
|
|
539
583
|
`function Start-GatewayProcess {`,
|
|
540
584
|
` if (-not (Test-Path $launcher)) { Write-UpdateLog \"launcher script not found: $launcher\"; return }`,
|
|
@@ -548,17 +592,35 @@ async function updateService() {
|
|
|
548
592
|
` Start-Sleep -Seconds 1`,
|
|
549
593
|
` Write-UpdateLog 'waiting executable unlock'`,
|
|
550
594
|
` $moved = $false`,
|
|
551
|
-
`
|
|
595
|
+
` $lastMoveError = ''`,
|
|
596
|
+
` for ($i = 0; $i -lt 120; $i++) {`,
|
|
552
597
|
` try {`,
|
|
553
598
|
` if (Test-Path $backupExe) { Remove-Item $backupExe -Force -ErrorAction SilentlyContinue }`,
|
|
554
|
-
` Move-Item $currentExe $backupExe -Force`,
|
|
599
|
+
` Move-Item $currentExe $backupExe -Force -ErrorAction Stop`,
|
|
555
600
|
` $moved = $true`,
|
|
556
601
|
` break`,
|
|
557
602
|
` } catch {`,
|
|
603
|
+
` $lastMoveError = $_.Exception.Message`,
|
|
604
|
+
` if (($i % 5) -eq 0) { Write-UpdateLog \"move-item failed try=$i error=$lastMoveError\" }`,
|
|
605
|
+
` if (($i -gt 0) -and (($i % 10) -eq 0)) { try { Stop-GatewayProcess } catch { Write-UpdateLog \"retry stop failed: $($_.Exception.Message)\" } }`,
|
|
558
606
|
` Start-Sleep -Seconds 1`,
|
|
559
607
|
` }`,
|
|
560
608
|
` }`,
|
|
561
|
-
` if (-not $moved) {
|
|
609
|
+
` if (-not $moved) {`,
|
|
610
|
+
` $holders = ''`,
|
|
611
|
+
` try {`,
|
|
612
|
+
` $targetName = [System.IO.Path]::GetFileNameWithoutExtension($currentExe)`,
|
|
613
|
+
` $procs = Get-Process -Name $targetName -ErrorAction SilentlyContinue`,
|
|
614
|
+
` $infos = @()`,
|
|
615
|
+
` foreach ($proc in $procs) {`,
|
|
616
|
+
` try { $procPath = $proc.Path } catch { $procPath = '' }`,
|
|
617
|
+
` $infos += \"pid=$($proc.Id) path=$procPath\"`,
|
|
618
|
+
` }`,
|
|
619
|
+
` $holders = ($infos -join '; ')`,
|
|
620
|
+
` } catch { $holders = \"enumerate failed: $($_.Exception.Message)\" }`,
|
|
621
|
+
` Write-UpdateLog \"executable still locked, lastError=$lastMoveError, holders=$holders\"`,
|
|
622
|
+
` throw \"等待旧版本可执行文件解锁超时: lastError=$lastMoveError; holders=$holders\"`,
|
|
623
|
+
` }`,
|
|
562
624
|
` Write-UpdateLog 'moving new executable'`,
|
|
563
625
|
` Move-Item $tmpExe $currentExe -Force`,
|
|
564
626
|
` Start-Sleep -Seconds 1`,
|