This commit is contained in:
LASTA_DEV01\lasta
2026-05-19 20:31:52 +09:00
parent 00407e7a08
commit e260e5f218
104 changed files with 12898 additions and 1709 deletions

319
restart_all_servers.bat Normal file
View File

@@ -0,0 +1,319 @@
@echo off
setlocal
set "AI_RESTART_ROOT=%~dp0"
powershell -NoProfile -ExecutionPolicy Bypass -Command "$p='%~f0'; $s=Get-Content -LiteralPath $p -Raw; $m=':ps1'; $i=$s.LastIndexOf($m); if ($i -lt 0) { throw 'PowerShell payload marker not found.' }; Invoke-Expression $s.Substring($i + $m.Length)"
set "EXIT_CODE=%ERRORLEVEL%"
if "%~1"=="--no-pause" exit /b %EXIT_CODE%
echo.
if not "%EXIT_CODE%"=="0" echo [servers] Failed with exit code %EXIT_CODE%.
pause
exit /b %EXIT_CODE%
:ps1
$ErrorActionPreference = "Stop"
$root = (Resolve-Path -LiteralPath $env:AI_RESTART_ROOT).Path
$logDir = Join-Path $root ".server-logs"
New-Item -ItemType Directory -Force -Path $logDir | Out-Null
$ports = @(8000, 8001, 8002, 8003, 5173, 5174)
function Write-Step {
param([string] $Message)
Write-Host "[servers] $Message"
}
function Get-CommandPath {
param([string[]] $Candidates)
foreach ($candidate in $Candidates) {
if ([string]::IsNullOrWhiteSpace($candidate)) {
continue
}
if (Test-Path -LiteralPath $candidate) {
return (Resolve-Path -LiteralPath $candidate).Path
}
$cmd = Get-Command $candidate -ErrorAction SilentlyContinue
if ($cmd) {
return $cmd.Source
}
}
return $null
}
function Read-DotEnv {
param([string] $Path)
$result = @{}
if (-not (Test-Path -LiteralPath $Path)) {
return $result
}
foreach ($line in Get-Content -LiteralPath $Path) {
if ($line -match "^\s*$" -or $line -match "^\s*#") {
continue
}
if ($line -match "^\s*([^#=\s]+)\s*=\s*(.*)\s*$") {
$key = $matches[1]
$value = $matches[2].Trim()
if (
($value.StartsWith('"') -and $value.EndsWith('"')) -or
($value.StartsWith("'") -and $value.EndsWith("'"))
) {
$value = $value.Substring(1, $value.Length - 2)
}
$result[$key] = $value
}
}
return $result
}
function Stop-ExistingServers {
Write-Step "Stopping existing project servers."
$currentPid = $PID
$rootPattern = [regex]::Escape($root)
$commandPattern = "uvicorn|crawler_platform\.app\.main|ont_platform\.api|phase[0-9]_app|vite|npm(\.cmd)?\s+run\s+(dev|preview|start)"
$matched = Get-CimInstance Win32_Process | Where-Object {
if (-not $_.CommandLine) {
return $false
}
if ($_.ProcessId -eq $currentPid) {
return $false
}
$cmd = $_.CommandLine
return ($cmd -match $commandPattern) -and (
$cmd -match $rootPattern -or
$cmd -match "crawler_platform|ontology_platform|ont_platform"
)
}
foreach ($proc in $matched) {
Write-Step ("Killing process {0} ({1})" -f $proc.ProcessId, $proc.Name)
Stop-Process -Id $proc.ProcessId -Force -ErrorAction SilentlyContinue
}
$listeners = Get-NetTCPConnection -State Listen -ErrorAction SilentlyContinue |
Where-Object { $ports -contains $_.LocalPort } |
Select-Object -ExpandProperty OwningProcess -Unique
foreach ($pidToStop in $listeners) {
if ($pidToStop -and $pidToStop -ne $currentPid) {
Write-Step ("Killing listener on configured dev port, pid {0}" -f $pidToStop)
Stop-Process -Id $pidToStop -Force -ErrorAction SilentlyContinue
}
}
Start-Sleep -Milliseconds 800
}
function Invoke-LoggedCommand {
param(
[string] $FilePath,
[string[]] $Arguments,
[string] $WorkingDirectory,
[string] $LogName
)
$logPath = Join-Path $logDir $LogName
$stderrPath = Join-Path $logDir ($LogName -replace "\.log$", ".stderr.log")
Write-Step ("Running {0} {1}" -f (Split-Path -Leaf $FilePath), ($Arguments -join " "))
Remove-Item -LiteralPath $logPath, $stderrPath -Force -ErrorAction SilentlyContinue
$proc = Start-Process `
-FilePath $FilePath `
-ArgumentList $Arguments `
-WorkingDirectory $WorkingDirectory `
-RedirectStandardOutput $logPath `
-RedirectStandardError $stderrPath `
-WindowStyle Hidden `
-Wait `
-PassThru
$exitCode = $proc.ExitCode
if ($exitCode -ne 0) {
throw "Command failed with exit code $exitCode. See $logPath and $stderrPath"
}
}
function Start-LoggedServer {
param(
[string] $Name,
[int] $Port,
[string] $FilePath,
[string[]] $Arguments,
[string] $WorkingDirectory,
[hashtable] $Environment = @{}
)
$stdout = Join-Path $logDir "$Name-stdout.log"
$stderr = Join-Path $logDir "$Name-stderr.log"
Remove-Item -LiteralPath $stdout, $stderr -Force -ErrorAction SilentlyContinue
$previous = @{}
foreach ($key in $Environment.Keys) {
$previous[$key] = [Environment]::GetEnvironmentVariable($key, "Process")
[Environment]::SetEnvironmentVariable($key, [string] $Environment[$key], "Process")
}
try {
$proc = Start-Process `
-FilePath $FilePath `
-ArgumentList $Arguments `
-WorkingDirectory $WorkingDirectory `
-RedirectStandardOutput $stdout `
-RedirectStandardError $stderr `
-WindowStyle Hidden `
-PassThru
} finally {
foreach ($key in $Environment.Keys) {
[Environment]::SetEnvironmentVariable($key, $previous[$key], "Process")
}
}
Write-Step ("Started {0}: pid {1}" -f $Name, $proc.Id)
return [pscustomobject]@{
Name = $Name
Port = $Port
Pid = $proc.Id
Stdout = $stdout
Stderr = $stderr
}
}
function Wait-Port {
param(
[int] $Port,
[int] $Seconds = 20
)
$deadline = (Get-Date).AddSeconds($Seconds)
while ((Get-Date) -lt $deadline) {
try {
$client = [System.Net.Sockets.TcpClient]::new()
$async = $client.BeginConnect("127.0.0.1", $Port, $null, $null)
if ($async.AsyncWaitHandle.WaitOne(500)) {
$client.EndConnect($async)
$client.Close()
return $true
}
$client.Close()
} catch {
Start-Sleep -Milliseconds 500
}
}
return $false
}
function Start-Neo4jIfAvailable {
$composeFile = Join-Path $root "docker-compose.neo4j.yml"
if (-not (Test-Path -LiteralPath $composeFile)) {
return
}
$docker = Get-CommandPath @("docker")
if (-not $docker) {
Write-Step "Docker was not found; skipping Neo4j compose service."
return
}
try {
Invoke-LoggedCommand -FilePath $docker -Arguments @("compose", "-f", $composeFile, "down") -WorkingDirectory $root -LogName "neo4j-down.log"
Invoke-LoggedCommand -FilePath $docker -Arguments @("compose", "-f", $composeFile, "up", "-d") -WorkingDirectory $root -LogName "neo4j-up.log"
Write-Step "Neo4j compose service requested."
} catch {
Write-Step "Neo4j compose restart skipped/failed. See .server-logs\\neo4j-*.log"
}
}
Stop-ExistingServers
Start-Neo4jIfAvailable
$npm = Get-CommandPath @("npm.cmd", "npm")
$frontendDir = Join-Path $root "crawler_platform\app\web\frontend"
if ((Test-Path -LiteralPath (Join-Path $frontendDir "package.json")) -and $npm) {
if (-not (Test-Path -LiteralPath (Join-Path $frontendDir "node_modules"))) {
Invoke-LoggedCommand -FilePath $npm -Arguments @("ci") -WorkingDirectory $frontendDir -LogName "frontend-npm-ci.log"
}
Invoke-LoggedCommand -FilePath $npm -Arguments @("run", "build") -WorkingDirectory $frontendDir -LogName "frontend-build.log"
} elseif (Test-Path -LiteralPath (Join-Path $frontendDir "package.json")) {
Write-Step "npm was not found; skipping frontend rebuild."
}
$servers = @()
$crawlerPython = Get-CommandPath @(
(Join-Path $root ".venv\Scripts\python.exe"),
(Join-Path $root "venv\Scripts\python.exe"),
"C:\Users\lasta\AppData\Local\Python\bin\python.exe",
"C:\Users\lasta\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe",
"python"
)
if ((Test-Path -LiteralPath (Join-Path $root "crawler_platform\app\main.py")) -and $crawlerPython) {
$servers += Start-LoggedServer `
-Name "crawler-platform-8000" `
-Port 8000 `
-FilePath $crawlerPython `
-Arguments @("-m", "uvicorn", "crawler_platform.app.main:app", "--host", "127.0.0.1", "--port", "8000") `
-WorkingDirectory $root `
-Environment @{ CRAWLER_DATABASE_URL = "sqlite:///crawler_platform.db" }
} else {
Write-Step "crawler_platform server entrypoint or Python was not found; skipped."
}
$ontologyRoot = Join-Path $root "ontology_platform"
$ontologyPython = Get-CommandPath @(
(Join-Path $ontologyRoot ".venv\Scripts\python.exe"),
(Join-Path $root ".venv\Scripts\python.exe"),
"C:\Users\lasta\AppData\Local\Python\bin\python.exe",
"C:\Users\lasta\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe",
"python"
)
if ((Test-Path -LiteralPath (Join-Path $ontologyRoot "ont_platform\api\main.py")) -and $ontologyPython) {
$ontologyEnv = Read-DotEnv -Path (Join-Path $ontologyRoot ".env")
$ontologyEnv["PHASE"] = "6"
$ontologyEnv["HOST"] = "127.0.0.1"
$ontologyEnv["PORT"] = "8001"
$servers += Start-LoggedServer `
-Name "ontology-platform-8001" `
-Port 8001 `
-FilePath $ontologyPython `
-Arguments @("-m", "uvicorn", "ont_platform.api.main:app", "--host", "127.0.0.1", "--port", "8001") `
-WorkingDirectory $ontologyRoot `
-Environment $ontologyEnv
} else {
Write-Step "ontology_platform server entrypoint or Python was not found; skipped."
}
$pidFile = Join-Path $logDir "server-pids.txt"
$servers | ForEach-Object {
"{0} pid={1} stdout={2} stderr={3}" -f $_.Name, $_.Pid, $_.Stdout, $_.Stderr
} | Set-Content -LiteralPath $pidFile -Encoding UTF8
$missingPorts = @()
foreach ($port in ($servers | Select-Object -ExpandProperty Port -Unique)) {
if (Wait-Port -Port $port -Seconds 25) {
Write-Step ("Port {0} is listening." -f $port)
} else {
Write-Step ("Port {0} did not open. Check logs in {1}" -f $port, $logDir)
$missingPorts += $port
}
}
if ($missingPorts.Count -gt 0) {
throw "Some servers did not start: ports $($missingPorts -join ', ')"
}
Write-Host ""
Write-Step "Done."
Write-Host " Crawler UI/API: http://127.0.0.1:8000/static/"
Write-Host " Crawler crawl page: http://127.0.0.1:8000/static/crawl/PerfumeSubscribe_new"
Write-Host " Ontology API: http://127.0.0.1:8001/docs"
Write-Host " Logs: $logDir"