-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun-demo.ps1
More file actions
346 lines (296 loc) · 10.2 KB
/
Copy pathrun-demo.ps1
File metadata and controls
346 lines (296 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
<# ======================================================================
Entropy Engine MVP – demo launcher (Windows PowerShell)
- Creates/uses .\venv
- Installs requirements when missing
- Starts test_stream_gen.py (TCP) and ee_mvp.py (Dash)
- Waits for UI to be healthy, then opens browser
- Tracks PIDs for clean shutdown
Usage (defaults):
.\run-demo.ps1
Examples:
.\run-demo.ps1 -GenPort 9109 -UiPort 8060 -AutoBumpPorts `
-VizArrowMode cone -VizTail -VizArrowGain 1.4 -VizYG 2 -VizZG 4 -VizAspect "1,1,1.6"
Stop processes:
.\run-demo.ps1 -Stop
====================================================================== #>
[CmdletBinding()]
param(
# ---- Generator knobs ----
[int] $GenPort = 9109, # TCP port to listen on
[string] $GenHost = "127.0.0.1",
[ValidateSet("123","abc","sym","mix")]
[string] $Datatype = "123",
[double] $Clock = 0.25, # seconds per tick
[int] $Runtime = 0, # 0 = run until stopped
[double] $Uf = 0.2, # unexpected factor 0..1
[int] $Seed = 42,
[ValidateSet("plain","json")]
[string] $Fmt = "plain",
# ---- MVP knobs ----
[double] $Dt = 0.25,
[int] $Bins = 24,
[double] $Window = 180,
[double] $Alpha = 0.2,
[double] $Tstar = 0.0,
# ---- UI (Dash) ----
[string] $UiHost = "127.0.0.1",
[int] $UiPort = 8050,
# ---- Visualization tuning (visual-only) ----
[switch] $VizTail,
[ValidateSet("cone","line")]
[string] $VizArrowMode = "cone",
[double] $VizArrowGain = 1.0,
[double] $VizYG = 1.0, # Y gain
[double] $VizZG = 1.0, # Z gain
[string] $VizAspect = "auto", # "x,y,z" or "auto"
[double] $VizConeSizeRef = 0.6,
[ValidateSet("absolute","scaled")]
[string] $VizConeSizeMode = "absolute",
# ---- Behavior ----
[switch] $AutoBumpPorts, # auto-try next ports if in use (Gen/UI)
[int] $MaxPortAttempts = 5,
[switch] $Stop # kill previously spawned generator/UI PIDs
)
# --- Helpers -------------------------------------------------------------
function Write-Info { param([string]$m) Write-Host "[demo] $m" -ForegroundColor Cyan }
function Write-Ok { param([string]$m) Write-Host "[demo] $m" -ForegroundColor Green }
function Write-Warn { param([string]$m) Write-Host "[demo] $m" -ForegroundColor Yellow }
function Write-Err { param([string]$m) Write-Host "[demo] $m" -ForegroundColor Red }
$Here = Split-Path -Parent $MyInvocation.MyCommand.Path
Set-Location $Here
$VenvPy = Join-Path $Here "venv\Scripts\python.exe"
$ReqTxt = Join-Path $Here "requirements.txt"
$GenPy = Join-Path $Here "test_stream_gen.py"
$MvpPy = Join-Path $Here "ee_mvp.py"
$PidFile= Join-Path $Here ".demo_pids.json"
function Get-PortOwner {
param([int]$Port)
$lines = netstat -ano -p tcp | Select-String ":$Port"
if (-not $lines) { return $null }
foreach ($line in $lines) {
$tokens = $line.ToString() -split '\s+'
if ($tokens.Length -ge 5 -and $tokens[-1] -match '^\d+$') {
return [int]$tokens[-1]
}
}
return $null
}
function Test-PortFree {
param([int]$Port)
return -not (Get-PortOwner -Port $Port)
}
function Ensure-Venv {
if (-not (Test-Path $VenvPy)) {
Write-Info "creating venv …"
& python -m venv "$Here\venv"
if ($LASTEXITCODE -ne 0 -or -not (Test-Path $VenvPy)) {
Write-Err "failed to create venv; ensure Python is installed and on PATH."
exit 1
}
}
}
function Ensure-Requirements {
Write-Info "installing requirements …"
& $VenvPy -m pip --version | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Err "pip not available in venv"
exit 1
}
& $VenvPy -m pip install --upgrade pip | Out-Null
if (Test-Path $ReqTxt) {
& $VenvPy -m pip install -r $ReqTxt
} else {
& $VenvPy -m pip install numpy pandas plotly dash
}
if ($LASTEXITCODE -ne 0) {
Write-Err "pip install failed"
exit 1
}
}
function Start-Generator {
param([int]$Port,[string]$GenHostParam)
if (-not (Test-Path $GenPy)) { Write-Err "missing $GenPy"; exit 1 }
$attempt = 0
$usePort = $Port
while ($true) {
if (Test-PortFree -Port $usePort) { break }
if (-not $AutoBumpPorts -or $attempt -ge $MaxPortAttempts) {
$pid = Get-PortOwner -Port $usePort
Write-Err "GenPort $usePort is in use (PID=$pid). Use -GenPort or -AutoBumpPorts."
exit 1
}
$attempt++
$usePort++
Write-Warn "GenPort in use; trying $usePort …"
}
$args = @(
$GenPy, "--mode","tcp",
"--datatype", $Datatype,
"--clock", "$Clock",
"--runtime", "$Runtime",
"--uf", "$Uf",
"--seed", "$Seed",
"--host", $GenHostParam,
"--port", "$usePort",
"--fmt", $Fmt
)
Write-Info "starting generator on $($GenHostParam):$usePort …"
$p = Start-Process -PassThru -WindowStyle Minimized -FilePath $VenvPy -ArgumentList $args
if (-not $p) { Write-Err "failed to start generator"; exit 1 }
return @{ PID = $p.Id; Port = $usePort }
}
function Start-MVP {
param([int]$GenPortUsed,[int]$UiPortWanted)
if (-not (Test-Path $MvpPy)) { Write-Err "missing $MvpPy"; exit 1 }
$attempt = 0
$ui = $UiPortWanted
while ($true) {
if (Test-PortFree -Port $ui) { break }
if (-not $AutoBumpPorts -or $attempt -ge $MaxPortAttempts) {
$pid = Get-PortOwner -Port $ui
Write-Err "UiPort $ui is in use (PID=$pid). Use -UiPort or -AutoBumpPorts."
exit 1
}
$attempt++
$ui++
Write-Warn "UiPort in use; trying $ui …"
}
$vizTailArg = $null
if ($VizTail) { $vizTailArg = "--viz_tail" }
$args = @(
$MvpPy,
"--source","tcp",
"--tcp_host",$GenHost,
"--tcp_port","$GenPortUsed",
"--dt","$Dt","--bins","$Bins","--window","$Window","--alpha","$Alpha","--Tstar","$Tstar",
"--ui_host",$UiHost,"--ui_port","$ui",
"--viz_arrow_mode",$VizArrowMode,
"--viz_arrow_gain","$VizArrowGain",
"--viz_y_gain","$VizYG",
"--viz_z_gain","$VizZG",
"--viz_aspect",$VizAspect,
"--viz_cone_sizeref","$VizConeSizeRef",
"--viz_cone_sizemode",$VizConeSizeMode
)
if ($vizTailArg) { $args += $vizTailArg }
Write-Info "starting MVP (UI $($UiHost):$ui, gen port $GenPortUsed) …"
$p = Start-Process -PassThru -WindowStyle Normal -FilePath $VenvPy -ArgumentList $args
if (-not $p) { Write-Err "failed to start MVP"; exit 1 }
return @{ PID = $p.Id; UiPort = $ui }
}
function Wait-UiAndOpen {
param([string]$Url,[int]$MaxTries = 40,[int]$DelayMs = 250)
Write-Info "waiting for UI $Url …"
for ($i=0; $i -lt $MaxTries; $i++) {
try {
Invoke-WebRequest -UseBasicParsing -TimeoutSec 2 -Uri $Url | Out-Null
Start-Process $Url | Out-Null
Write-Ok "UI is ready → $Url"
return $true
} catch {
Start-Sleep -Milliseconds $DelayMs
}
}
Write-Warn "UI not reachable yet (you can open $Url manually when it’s up)."
return $false
}
function Save-PIDs {
param([int]$GenPID,[int]$MvpPID,[int]$GenPortUsed,[int]$UiPortUsed)
$obj = [ordered]@{
generator_pid = $GenPID
mvp_pid = $MvpPID
gen_port = $GenPortUsed
ui_port = $UiPortUsed
saved_at = (Get-Date).ToString("s")
}
$obj | ConvertTo-Json | Set-Content -Encoding UTF8 $PidFile
}
function Stop-Previous {
if (-not (Test-Path $PidFile)) {
Write-Warn "no .demo_pids.json found; nothing to stop."
return
}
$state = Get-Content $PidFile | ConvertFrom-Json
$pids = @()
if ($state.generator_pid) { $pids += [int]$state.generator_pid }
if ($state.mvp_pid) { $pids += [int]$state.mvp_pid }
if ($pids.Count -eq 0) {
Write-Warn "no PIDs recorded."
return
}
foreach ($pid in $pids) {
try {
Write-Info "stopping PID $pid …"
Stop-Process -Id $pid -Force -ErrorAction Stop
} catch {
Write-Warn "could not stop PID $pid (may already be closed)"
}
}
Remove-Item -ErrorAction SilentlyContinue $PidFile
Write-Ok "stopped recorded demo processes."
}
# --- Stop mode? ----------------------------------------------------------
if ($Stop) {
Stop-Previous
exit 0
}
# --- Main flow -----------------------------------------------------------
Write-Info "project: $Here"
Ensure-Venv
Ensure-Requirements
# Sanity check: can we import numpy/plotly?
# Sanity check: can we import numpy/plotly?
Write-Info "sanity import check …"
$pyCheck = @'
import sys, importlib, importlib.util
mods = ["numpy", "plotly"]
missing = [m for m in mods if importlib.util.find_spec(m) is None]
if missing:
print("MISSING: " + ", ".join(missing))
sys.exit(1)
else:
print("OK")
sys.exit(0)
'@
# Write to a temp file (safer than -c / here-doc in PowerShell), run, and clean up
$tmpPy = [System.IO.Path]::GetTempFileName().Replace(".tmp",".py")
[System.IO.File]::WriteAllText($tmpPy, $pyCheck, [System.Text.Encoding]::UTF8)
& $VenvPy $tmpPy
$code = $LASTEXITCODE
Remove-Item -ErrorAction SilentlyContinue $tmpPy
if ($code -ne 0) {
Write-Err "Python packages missing. Try: `"$VenvPy`" -m pip install -r requirements.txt"
exit 1
}
#Write-Info "sanity import check …"
#$pyOneLiner = @"
#import importlib, sys
#mods = ["numpy", "plotly"]
#missing = [m for m in mods if importlib.util.find_spec(m) is None]
#if missing:
# print("MISSING: " + ", ".join(missing))
# sys.exit(1)
#print("OK")
#"@
#$pyOneLiner = ($pyOneLiner -split "`r?`n" | Where-Object { $_ -ne "" }) -join "; "
#& $VenvPy -c $pyOneLiner
#if ($LASTEXITCODE -ne 0) {
# Write-Err "Python packages missing. Try: `"$VenvPy`" -m pip install -r requirements.txt"
# exit 1
#}
# Start generator (with port bump if asked)
$gen = Start-Generator -Port $GenPort -GenHostParam $GenHost
$genPid = $gen.PID
$genPort = $gen.Port
Write-Ok "generator PID=$genPid on $($GenHost):$genPort"
Start-Sleep -Milliseconds 600 # small warmup
# Start MVP and wait for UI
$mvp = Start-MVP -GenPortUsed $genPort -UiPortWanted $UiPort
$mvpPid = $mvp.PID
$uiPort = $mvp.UiPort
Write-Ok "mvp PID=$mvpPid (UI port $uiPort)"
$uiUrl = "http://$($UiHost):$uiPort/"
Wait-UiAndOpen -Url $uiUrl | Out-Null
# Persist PIDs for Stop
Save-PIDs -GenPID $genPid -MvpPID $mvpPid -GenPortUsed $genPort -UiPortUsed $uiPort
Write-Ok "demo launched. Close windows or run '.\run-demo.ps1 -Stop' to shut down."