返回 DeepSeek-Reasonix
state.go
根目录 / internal / remote / bootstrap / state.go
1 package bootstrap
2
3 import (
4 "encoding/json"
5 "path"
6 "time"
7
8 "reasonix/internal/store"
9 )
10
11 // ServeState is the JSON record a bootstrapped serve leaves on the remote host
12 // so a later (re)connect can find and reuse it. Fields use omitempty so an
13 // older record missing a field still decodes.
14 type ServeState struct {
15 PID int `json:"pid"`
16 Addr string `json:"addr"` // 127.0.0.1:<port> on the remote host
17 Workspace string `json:"workspace"`
18 Version string `json:"version,omitempty"`
19 ServeCaps string `json:"serve_caps,omitempty"`
20 TokenFile string `json:"token_file"`
21 LogFile string `json:"log_file,omitempty"`
22 StartedAt int64 `json:"started_at,omitempty"` // unix seconds
23 }
24
25 // MarshalState renders a ServeState as indented JSON.
26 func MarshalState(s ServeState) ([]byte, error) {
27 return json.MarshalIndent(s, "", " ")
28 }
29
30 // UnmarshalState parses a ServeState record.
31 func UnmarshalState(data []byte) (ServeState, error) {
32 var s ServeState
33 if err := json.Unmarshal(data, &s); err != nil {
34 return ServeState{}, err
35 }
36 return s, nil
37 }
38
39 // remoteDir is the ~/.reasonix/remote directory given the resolved remote home.
40 func remoteDir(home string) string {
41 return path.Join(home, ".reasonix", store.RemoteDirName)
42 }
43
44 // pathsFor derives every per-workspace state path from the resolved remote
45 // home and workspace directory.
46 func pathsFor(home, workspace string) StatePaths {
47 dir := remoteDir(home)
48 slug := store.RemoteWorkspaceSlug(workspace)
49 return StatePaths{
50 Dir: dir,
51 StateJSON: path.Join(dir, store.RemoteServeStateName(slug)),
52 TokenFile: path.Join(dir, store.RemoteServeTokenName(slug)),
53 LogFile: path.Join(dir, store.RemoteServeLogName(slug)),
54 PortFile: path.Join(dir, store.RemoteServePortName(slug)),
55 PidFile: path.Join(dir, store.RemoteServePidName(slug)),
56 LockDir: path.Join(dir, store.RemoteServeLockName(slug)),
57 LockOwner: path.Join(dir, store.RemoteServeLockName(slug), "owner"),
58 }
59 }
60
61 // uploadedBinPath is the fallback location for an uploaded reasonix binary.
62 func uploadedBinPath(home string) string {
63 return path.Join(remoteDir(home), store.RemoteBinDirName, "reasonix")
64 }
65
66 func nowUnix(clock func() time.Time) int64 {
67 if clock == nil {
68 return 0
69 }
70 return clock().Unix()
71 }
72
72 lines GO