157 lines
2.8 KiB
Go
157 lines
2.8 KiB
Go
package writeserver
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
mu sync.Mutex
|
|
writeProc *exec.Cmd
|
|
writeReady bool
|
|
hugoProc *exec.Cmd
|
|
WritePort int
|
|
WriteDir string
|
|
)
|
|
|
|
func Init(writePort int, writeDir string) {
|
|
WritePort = writePort
|
|
WriteDir = writeDir
|
|
}
|
|
|
|
func StartWriteServer() map[string]interface{} {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
if writeProc != nil {
|
|
if writeReady {
|
|
return map[string]interface{}{"started": false, "reason": "already_running"}
|
|
}
|
|
return map[string]interface{}{"started": false, "reason": "starting"}
|
|
}
|
|
|
|
writeReady = false
|
|
writeProc = exec.Command(filepath.Join(WriteDir, "writeserver.exe"))
|
|
writeProc.Dir = WriteDir
|
|
|
|
if err := writeProc.Start(); err != nil {
|
|
writeProc = nil
|
|
return map[string]interface{}{"started": false, "reason": err.Error()}
|
|
}
|
|
|
|
writeReady = true
|
|
|
|
go func() {
|
|
err := writeProc.Wait()
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
fmt.Printf("[write] exited: %v\n", err)
|
|
writeProc = nil
|
|
writeReady = false
|
|
}()
|
|
|
|
return map[string]interface{}{"started": true}
|
|
}
|
|
|
|
func StopWriteServer() bool {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
if hugoProc != nil {
|
|
killProcessTree(hugoProc)
|
|
hugoProc = nil
|
|
}
|
|
|
|
if writeProc == nil {
|
|
return false
|
|
}
|
|
|
|
killProcessTree(writeProc)
|
|
writeProc = nil
|
|
writeReady = false
|
|
return true
|
|
}
|
|
|
|
func killProcessTree(cmd *exec.Cmd) {
|
|
if cmd == nil || cmd.Process == nil {
|
|
return
|
|
}
|
|
// On Windows, use taskkill /T to kill process tree
|
|
pid := cmd.Process.Pid
|
|
killCmd := exec.Command("taskkill", "/PID", fmt.Sprintf("%d", pid), "/T", "/F")
|
|
killCmd.Run()
|
|
cmd.Process.Kill()
|
|
}
|
|
|
|
func StartHugoIfNeeded() {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
if hugoProc != nil {
|
|
return
|
|
}
|
|
|
|
hugoDir := WriteDir + "/.."
|
|
hugoProc = exec.Command("hugo", "server", "--bind", "0.0.0.0", "--port", "1313", "--disableFastRender")
|
|
hugoProc.Dir = hugoDir
|
|
|
|
if err := hugoProc.Start(); err != nil {
|
|
fmt.Printf("[hugo] start error: %v\n", err)
|
|
hugoProc = nil
|
|
return
|
|
}
|
|
|
|
fmt.Println("[hugo] started on 0.0.0.0:1313")
|
|
|
|
go func() {
|
|
err := hugoProc.Wait()
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
fmt.Printf("[hugo] exited: %v\n", err)
|
|
hugoProc = nil
|
|
}()
|
|
}
|
|
|
|
func GetWriteStatus() map[string]interface{} {
|
|
mu.Lock()
|
|
running := writeProc != nil && writeReady
|
|
starting := writeProc != nil && !writeReady
|
|
mu.Unlock()
|
|
|
|
// Also check via TCP if we are not tracking a process
|
|
if !running && !starting {
|
|
conn, err := net.DialTimeout("tcp", fmt.Sprintf("127.0.0.1:%d", WritePort), 2*time.Second)
|
|
if err == nil {
|
|
conn.Close()
|
|
running = true
|
|
}
|
|
}
|
|
|
|
return map[string]interface{}{
|
|
"running": running,
|
|
"starting": starting,
|
|
}
|
|
}
|
|
|
|
func SetWriteReady(ready bool) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
writeReady = ready
|
|
}
|
|
|
|
func IsWriteReady() bool {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
return writeReady
|
|
}
|
|
|
|
func IsWriteRunning() bool {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
return writeProc != nil
|
|
}
|