| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- #Requires -Version 7.0
- param(
- [ValidateSet('Prepare', 'Stop')]
- [string] $Action = 'Prepare',
- [ValidatePattern('^[a-zA-Z0-9][a-zA-Z0-9_-]{0,47}$')]
- [string] $Session,
- [ValidateRange(1, 180)]
- [int] $DurationMinutes = 180
- )
- $ErrorActionPreference = 'Stop'
- $demoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
- $demoDirectory = Join-Path $demoRoot '.work/course-demo'
- $demoScript = Join-Path $PSScriptRoot 'prepare_course_demo.py'
- $demoPython = Join-Path $demoRoot '.venv/Scripts/python.exe'
- $demoProcessFile = Join-Path $demoDirectory 'sync-process.json'
- function Stop-DemoSync {
- if (-not (Test-Path -LiteralPath $demoProcessFile)) { return }
- $record = Get-Content -LiteralPath $demoProcessFile -Raw | ConvertFrom-Json
- $process = Get-Process -Id $record.pid -ErrorAction SilentlyContinue
- if ($null -eq $process) { return }
- $details = Get-CimInstance Win32_Process -Filter "ProcessId = $($record.pid)"
- # 仅停止本入口登记且创建时间一致的同步进程,防止 PID 被其他程序复用。
- if ($process.StartTime.ToUniversalTime().Ticks -ne [long]$record.started_ticks -or
- $null -eq $details.CommandLine -or -not $details.CommandLine.Contains($demoScript)) {
- throw '订单同步进程身份检查失败,请检查进程记录。'
- }
- $process.Kill($true)
- if (-not $process.WaitForExit(10000)) { throw '订单同步进程未在十秒内停止。' }
- }
- Push-Location $demoRoot
- try {
- if ($Action -eq 'Stop') {
- Stop-DemoSync
- Write-Output '课程订单同步已停止,课程数据保留。'
- return
- }
- if (-not (Test-Path -LiteralPath $demoPython)) { throw '请准备项目 Python 环境。' }
- if (-not $Session) { $Session = Get-Date -Format 'yyyyMMdd-HHmmss-fff' }
- $env:PYTHONUTF8 = '1'
- $env:PYTHONIOENCODING = 'utf-8'
- & $demoPython $demoScript prepare --session $Session
- if ($LASTEXITCODE -ne 0) { throw '课程订单准备失败。' }
- # 履约进程读取已登记的专用 OMS 凭据;Compose 保留现有数据库与其他服务。
- $env:ZHIFU_RUNTIME_ENV = (Resolve-Path '.work/runtime.env').Path
- $env:ZHIFU_MODEL_PATH = (Resolve-Path '.work/models').Path
- docker compose -f compose.runtime.yaml up -d --no-deps fulfillment
- if ($LASTEXITCODE -ne 0) { throw '履约进程配置加载失败。' }
- Stop-DemoSync
- $durationSeconds = $DurationMinutes * 60
- $arguments = @(('"' + $demoScript + '"'), 'sync', '--session', $Session,
- '--duration-seconds', "$durationSeconds", '--interval-seconds', '60')
- $stdout = Join-Path $demoDirectory "$Session-sync.stdout.log"
- $stderr = Join-Path $demoDirectory "$Session-sync.stderr.log"
- $process = Start-Process -FilePath $demoPython -ArgumentList $arguments `
- -WorkingDirectory $demoRoot -WindowStyle Hidden -PassThru `
- -RedirectStandardOutput $stdout -RedirectStandardError $stderr
- @{pid = $process.Id; started_ticks = $process.StartTime.ToUniversalTime().Ticks;
- session = $Session; duration_seconds = $durationSeconds; interval_seconds = 60;
- stdout = $stdout; stderr = $stderr} |
- ConvertTo-Json | Set-Content -LiteralPath $demoProcessFile -Encoding utf8
- if ($process.WaitForExit(3000)) {
- Get-Content -LiteralPath $stderr
- throw '订单同步进程提前结束。'
- }
- Write-Output "课程 $Session 已准备;每 60 秒从 OMS 同步一次,最长 $DurationMinutes 分钟。"
- Write-Output "本次账户及订单:$demoDirectory/active.json"
- } finally {
- Pop-Location
- }
|