返回 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 TokenFile string `json:"token_file"`
20 LogFile string `json:"log_file,omitempty"`
21 StartedAt int64 `json:"started_at,omitempty"` // unix seconds
22 }
23
24 // MarshalState renders a ServeState as indented JSON.
25 func MarshalState(s ServeState) ([]byte, error) {
26 return json.MarshalIndent(s, "", " ")
27 }
28
29 // UnmarshalState parses a ServeState record.
30 func UnmarshalState(data []byte) (ServeState, error) {
31 var s ServeState
32 if err := json.Unmarshal(data, &s); err != nil {
33 return ServeState{}, err
34 }
35 return s, nil
36 }
37
38 // remoteDir is the ~/.reasonix/remote directory given the resolved remote home.
39 func remoteDir(home string) string {
40 return path.Join(home, ".reasonix", store.RemoteDirName)
41 }
42
43 // pathsFor derives every per-workspace state path from the resolved remote
44 // home and workspace directory.
45 func pathsFor(home, workspace string) StatePaths {
46 dir := remoteDir(home)
47 slug := store.RemoteWorkspaceSlug(workspace)
48 return StatePaths{
49 Dir: dir,
50 StateJSON: path.Join(dir, store.RemoteServeStateName(slug)),
51 TokenFile: path.Join(dir, store.RemoteServeTokenName(slug)),
52 LogFile: path.Join(dir, store.RemoteServeLogName(slug)),
53 PortFile: path.Join(dir, store.RemoteServePortName(slug)),
54 PidFile: path.Join(dir, store.RemoteServePidName(slug)),
55 LockDir: path.Join(dir, store.RemoteServeLockName(slug)),
56 LockOwner: path.Join(dir, store.RemoteServeLockName(slug), "owner"),
57 }
58 }
59
60 // uploadedBinPath is the fallback location for an uploaded reasonix binary.
61 func uploadedBinPath(home string) string {
62 return path.Join(remoteDir(home), store.RemoteBinDirName, "reasonix")
63 }
64
65 func nowUnix(clock func() time.Time) int64 {
66 if clock == nil {
67 return 0
68 }
69 return clock().Unix()
70 }
71
71 lines GO