juc500 정상동작

This commit is contained in:
Macbook
2026-07-21 21:04:25 +09:00
parent a423db0556
commit bb9874b931
2917 changed files with 708025 additions and 668 deletions
+117
View File
@@ -0,0 +1,117 @@
use std::net::{SocketAddr, TcpStream};
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Stdio};
use std::time::{Duration, Instant};
pub const GUI_PORT: u16 = 8765;
/// Project root containing `juc500_app.py` (parent of `juc500-app/` in dev).
pub fn project_root() -> PathBuf {
if let Ok(root) = std::env::var("JUC500_ROOT") {
let p = PathBuf::from(root);
if p.join("juc500_app.py").is_file() {
return p;
}
}
if let Ok(cwd) = std::env::current_dir() {
if cwd.join("juc500_app.py").is_file() {
return cwd;
}
let parent = cwd.parent().map(Path::to_path_buf);
if let Some(ref p) = parent {
if p.join("juc500_app.py").is_file() {
return p.clone();
}
}
}
if let Ok(exe) = std::env::current_exe() {
let mut dir = exe.parent().map(Path::to_path_buf);
for _ in 0..10 {
let Some(ref d) = dir else { break };
if d.join("juc500_app.py").is_file() {
return d.clone();
}
if d.join("..").join("juc500_app.py").exists() {
if let Ok(canon) = d.join("..").canonicalize() {
if canon.join("juc500_app.py").is_file() {
return canon;
}
}
}
dir = d.parent().map(Path::to_path_buf);
}
}
PathBuf::from(".")
}
pub fn resolve_python(root: &Path) -> PathBuf {
if cfg!(windows) {
let venv = root.join(".venv").join("Scripts").join("python.exe");
if venv.is_file() {
return venv;
}
} else {
let venv = root.join(".venv").join("bin").join("python");
if venv.is_file() {
return venv;
}
}
if cfg!(windows) {
PathBuf::from("python")
} else {
PathBuf::from("python3")
}
}
pub fn kill_wormhole(root: &Path) {
let py = resolve_python(root);
let _ = Command::new(&py)
.current_dir(root)
.env("PYTHONPATH", root)
.args([
"-c",
"from juc500_xfer.wormhole_kill import kill_wormhole_processes; \
kill_wormhole_processes(force=True)",
])
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
}
pub fn backend_running(port: u16) -> bool {
let addr: SocketAddr = format!("127.0.0.1:{}", port).parse().unwrap();
TcpStream::connect_timeout(&addr, Duration::from_millis(200)).is_ok()
}
pub fn wait_backend(port: u16, timeout: Duration) -> bool {
let deadline = Instant::now() + timeout;
while Instant::now() < deadline {
if backend_running(port) {
return true;
}
std::thread::sleep(Duration::from_millis(200));
}
false
}
pub fn start_backend(root: &Path) -> std::io::Result<Child> {
kill_wormhole(root);
let py = resolve_python(root);
let app = root.join("juc500_app.py");
Command::new(&py)
.current_dir(root)
.env("PYTHONPATH", root)
.env("JUC500_TAURI", "1")
.arg(&app)
.arg("--backend")
.stdout(Stdio::null())
.stderr(Stdio::piped())
.spawn()
}
pub fn stop_backend(child: &mut Option<Child>) {
if let Some(mut c) = child.take() {
let _ = c.kill();
let _ = c.wait();
}
}