Skip to content

Commit 743d0ac

Browse files
authored
refactor: isolate deps and save support internals (#11)
* refactor: isolate deps and save support internals * test: ignore zombie workers in broker fast tests
1 parent 66647f8 commit 743d0ac

15 files changed

Lines changed: 249 additions & 170 deletions

‎Beam.lean‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Beam.Broker.Deps
1010
import Beam.Broker.LakeSave
1111
import Beam.Broker.Lean
1212
import Beam.Broker.Protocol
13+
import Beam.Broker.StaleDirectDeps
1314
import Beam.Broker.SyncSaveSupport
1415
import Beam.Broker.Transport
1516
import Beam.Broker.UnixNative

‎Beam/Broker/Backend/Lean.lean‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import Lean
88
import Lean.Data.Lsp.Extra
99
import Lean.Data.Lsp.LanguageFeatures
1010
import RunAt.Protocol
11-
import RunAt.Internal.SaveArtifacts
11+
import RunAt.Internal.DirectImports
12+
import RunAt.Internal.SaveSupport
1213
import Beam.Broker.Config
1314
import Beam.Broker.Protocol
1415

‎Beam/Broker/Deps.lean‎

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,6 @@ def normalizeModuleForPath (root path : System.FilePath) (uri : DocumentUri) (mo
5858
| some name => some { name, uri }
5959
| none => none
6060

61-
structure DirectImportsQueryResult where
62-
version : Nat
63-
imports : Array String := #[]
64-
deriving Inhabited
65-
66-
structure ModuleHistorySnapshot where
67-
path : String
68-
lastSyncSeq : Nat := 0
69-
lastSaveSeq : Nat := 0
70-
deriving Inhabited
71-
72-
structure StaleDirectDepHint where
73-
module : String
74-
path : String
75-
needsSave : Bool
76-
lastSyncSeq : Nat
77-
lastSaveSeq : Nat
78-
deriving Inhabited
79-
8061
def moduleJson (root : System.FilePath) (module : LeanModule) : Json :=
8162
let path? := workspacePath? root module.uri
8263
Json.mkObj <|
@@ -106,54 +87,6 @@ def depsPayload (root : System.FilePath) (module : LeanModule)
10687
("importedByClosure", Json.arr <| importedByClosure.toList.map (fun (_, imp) => importJson root imp) |>.toArray)
10788
]
10889

109-
def staleDirectDepHintJson (hint : StaleDirectDepHint) : Json :=
110-
Json.mkObj [
111-
("module", toJson hint.module),
112-
("path", toJson hint.path),
113-
("needsSave", toJson hint.needsSave),
114-
("lastSyncSeq", toJson hint.lastSyncSeq),
115-
("lastSaveSeq", toJson hint.lastSaveSeq)
116-
]
117-
118-
def staleSyncErrorData
119-
(targetPath : String)
120-
(hints : Array StaleDirectDepHint) : Json :=
121-
let saveHints := hints.filter (·.needsSave)
122-
let recoveryPlan :=
123-
(saveHints.map fun hint => s!"lean-beam save \"{hint.path}\"") ++
124-
#[s!"lean-beam refresh \"{targetPath}\"", "lake build"]
125-
Json.mkObj [
126-
("targetPath", toJson targetPath),
127-
("staleDirectDeps", Json.arr <| hints.map staleDirectDepHintJson),
128-
("saveDeps", Json.arr <| saveHints.map (fun hint => toJson hint.path)),
129-
("recoveryPlan", Json.arr <| recoveryPlan.map toJson)
130-
]
131-
132-
def collectStaleDirectDepHints
133-
(importsResult : DirectImportsQueryResult)
134-
(version : Nat)
135-
(targetLastSyncSeq : Nat)
136-
(history : Std.TreeMap String ModuleHistorySnapshot)
137-
: Array StaleDirectDepHint :=
138-
if importsResult.version != version then
139-
#[]
140-
else
141-
importsResult.imports.foldl (init := #[]) fun hints moduleName =>
142-
match history.get? moduleName with
143-
| some moduleHistory =>
144-
if moduleHistory.lastSaveSeq > targetLastSyncSeq then
145-
hints.push {
146-
module := moduleName
147-
path := moduleHistory.path
148-
needsSave := moduleHistory.lastSaveSeq < moduleHistory.lastSyncSeq
149-
lastSyncSeq := moduleHistory.lastSyncSeq
150-
lastSaveSeq := moduleHistory.lastSaveSeq
151-
}
152-
else
153-
hints
154-
| none =>
155-
hints
156-
15790
def importInfoToWorkspaceImport?
15891
(moduleIndex : Std.TreeMap String System.FilePath)
15992
(info : ImportInfo) : Option LeanImport := do

‎Beam/Broker/Server.lean‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ import Lean.Data.Lsp.LanguageFeatures
1111
import Lean.Data.Lsp.Internal
1212
import Lean.Parser.Module
1313
import RunAt.Protocol
14-
import RunAt.Internal.SaveArtifacts
14+
import RunAt.Internal.DirectImports
15+
import RunAt.Internal.SaveSupport
1516
import Beam.Broker.Config
1617
import Beam.Broker.Protocol
1718
import Beam.Broker.Transport
1819
import Beam.Broker.Lean
1920
import Beam.Broker.Deps
2021
import Beam.Broker.LakeSave
22+
import Beam.Broker.StaleDirectDeps
2123
import Beam.Broker.SyncSaveSupport
2224
import Std.Sync.Mutex
2325

‎Beam/Broker/StaleDirectDeps.lean‎

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/-
2+
Copyright (c) 2026 Lean FRO LLC. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Author: Emilio J. Gallego Arias
5+
-/
6+
7+
import Lean
8+
9+
open Lean
10+
11+
namespace Beam.Broker
12+
13+
/--
14+
Data used by the supported sync/readiness path to explain stale direct dependencies after a failed
15+
diagnostics barrier.
16+
17+
This is intentionally separate from the stopgap `lean-deps` workspace scanner so the real sync
18+
recovery path does not conceptually depend on the experimental dependency-inspection surface.
19+
-/
20+
21+
structure DirectImportsQueryResult where
22+
version : Nat
23+
imports : Array String := #[]
24+
deriving Inhabited
25+
26+
structure ModuleHistorySnapshot where
27+
path : String
28+
lastSyncSeq : Nat := 0
29+
lastSaveSeq : Nat := 0
30+
deriving Inhabited
31+
32+
structure StaleDirectDepHint where
33+
module : String
34+
path : String
35+
needsSave : Bool
36+
lastSyncSeq : Nat
37+
lastSaveSeq : Nat
38+
deriving Inhabited
39+
40+
def staleDirectDepHintJson (hint : StaleDirectDepHint) : Json :=
41+
Json.mkObj [
42+
("module", toJson hint.module),
43+
("path", toJson hint.path),
44+
("needsSave", toJson hint.needsSave),
45+
("lastSyncSeq", toJson hint.lastSyncSeq),
46+
("lastSaveSeq", toJson hint.lastSaveSeq)
47+
]
48+
49+
def staleSyncErrorData
50+
(targetPath : String)
51+
(hints : Array StaleDirectDepHint) : Json :=
52+
let saveHints := hints.filter (·.needsSave)
53+
let recoveryPlan :=
54+
(saveHints.map fun hint => s!"lean-beam save \"{hint.path}\"") ++
55+
#[s!"lean-beam refresh \"{targetPath}\"", "lake build"]
56+
Json.mkObj [
57+
("targetPath", toJson targetPath),
58+
("staleDirectDeps", Json.arr <| hints.map staleDirectDepHintJson),
59+
("saveDeps", Json.arr <| saveHints.map (fun hint => toJson hint.path)),
60+
("recoveryPlan", Json.arr <| recoveryPlan.map toJson)
61+
]
62+
63+
def collectStaleDirectDepHints
64+
(importsResult : DirectImportsQueryResult)
65+
(version : Nat)
66+
(targetLastSyncSeq : Nat)
67+
(history : Std.TreeMap String ModuleHistorySnapshot)
68+
: Array StaleDirectDepHint :=
69+
if importsResult.version != version then
70+
#[]
71+
else
72+
importsResult.imports.foldl (init := #[]) fun hints moduleName =>
73+
match history.get? moduleName with
74+
| some moduleHistory =>
75+
if moduleHistory.lastSaveSeq > targetLastSyncSeq then
76+
hints.push {
77+
module := moduleName
78+
path := moduleHistory.path
79+
needsSave := moduleHistory.lastSaveSeq < moduleHistory.lastSyncSeq
80+
lastSyncSeq := moduleHistory.lastSyncSeq
81+
lastSaveSeq := moduleHistory.lastSaveSeq
82+
}
83+
else
84+
hints
85+
| none =>
86+
hints
87+
88+
end Beam.Broker

‎Beam/Broker/SyncSaveSupport.lean‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Author: Emilio J. Gallego Arias
55
-/
66

77
import Lean
8-
import RunAt.Internal.SaveArtifacts
8+
import RunAt.Internal.SaveSupport
99
import Beam.Broker.LakeSave
1010
import Beam.Broker.Protocol
1111

‎RunAt/Internal/DirectImports.lean‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/-
2+
Copyright (c) 2026 Lean FRO LLC. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Author: Emilio J. Gallego Arias
5+
-/
6+
7+
import Lean
8+
9+
open Lean
10+
11+
namespace RunAt.Internal
12+
13+
/--
14+
Internal broker-only request for parsing the current document header and returning its direct imports
15+
from the current tracked text snapshot.
16+
17+
This supports broker-side stale dependency hints and compatibility-only tooling. It is not part of
18+
the supported public `runAt` API.
19+
-/
20+
def directImportsMethod : String := "$/lean/runAt/directImports"
21+
22+
/-- Internal request payload for direct-import queries from the current tracked text snapshot. -/
23+
structure DirectImportsParams where
24+
textDocument : Lean.Lsp.TextDocumentIdentifier
25+
deriving FromJson, ToJson
26+
27+
instance : Lean.Lsp.FileSource DirectImportsParams where
28+
fileSource p := p.textDocument.uri
29+
30+
/-- Internal success payload for direct-import queries from the current tracked text snapshot. -/
31+
structure DirectImportsResult where
32+
version : Nat
33+
imports : Array String := #[]
34+
deriving FromJson, ToJson
35+
36+
end RunAt.Internal

‎RunAt/Internal/SaveArtifacts.lean‎

Lines changed: 13 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,17 @@
1-
/-
2-
Copyright (c) 2026 Lean FRO LLC. All rights reserved.
3-
Released under Apache 2.0 license as described in the file LICENSE.
4-
Author: Emilio J. Gallego Arias
5-
-/
1+
/-
2+
Copyright (c) 2026 Lean FRO LLC. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Author: Emilio J. Gallego Arias
5+
-/
66

7-
import Lean
7+
import RunAt.Internal.DirectImports
8+
import RunAt.Internal.SaveSupport
89

9-
open Lean
10+
/--
11+
Compatibility import for broker-only save support internals.
1012
11-
namespace RunAt.Internal
13+
The actual definitions now live in:
1214
13-
/--
14-
Internal broker-only request for saving the current elaborated document state to
15-
the Lake artifact locations expected by the workspace.
16-
17-
This is not part of the public `runAt` API.
18-
-/
19-
def saveArtifactsMethod : String := "$/lean/runAt/saveArtifacts"
20-
21-
/--
22-
Internal broker-only request for checking whether the current elaborated document
23-
state is ready for artifact save.
24-
25-
This is not part of the public `runAt` API.
26-
-/
27-
def saveReadinessMethod : String := "$/lean/runAt/saveReadiness"
28-
29-
/--
30-
Internal broker-only request for parsing the current document header and
31-
returning its direct imports from the current tracked text snapshot.
32-
33-
This is not part of the public `runAt` API.
34-
-/
35-
def directImportsMethod : String := "$/lean/runAt/directImports"
36-
37-
/-- Internal request payload for artifact serialization from the current worker snapshot. -/
38-
structure SaveArtifactsParams where
39-
textDocument : Lean.Lsp.TextDocumentIdentifier
40-
oleanFile : String
41-
ileanFile : String
42-
cFile : String
43-
bcFile? : Option String := none
44-
deriving FromJson, ToJson
45-
46-
instance : Lean.Lsp.FileSource SaveArtifactsParams where
47-
fileSource p := p.textDocument.uri
48-
49-
/-- Internal request payload for save-readiness checks from the current worker snapshot. -/
50-
structure SaveReadinessParams where
51-
textDocument : Lean.Lsp.TextDocumentIdentifier
52-
deriving FromJson, ToJson
53-
54-
instance : Lean.Lsp.FileSource SaveReadinessParams where
55-
fileSource p := p.textDocument.uri
56-
57-
/-- Internal request payload for direct-import queries from the current tracked text snapshot. -/
58-
structure DirectImportsParams where
59-
textDocument : Lean.Lsp.TextDocumentIdentifier
60-
deriving FromJson, ToJson
61-
62-
instance : Lean.Lsp.FileSource DirectImportsParams where
63-
fileSource p := p.textDocument.uri
64-
65-
/-- Internal success payload for artifact serialization. -/
66-
structure SaveArtifactsResult where
67-
written : Bool := true
68-
version : Nat
69-
textHash : UInt64
70-
deriving FromJson, ToJson
71-
72-
/-- Internal success payload for save-readiness checks. -/
73-
structure SaveReadinessResult where
74-
version : Nat
75-
diagnosticErrorCount : Nat := 0
76-
commandErrorCount : Nat := 0
77-
saveReady : Bool := true
78-
saveReadyReason : String := "ok"
79-
deriving FromJson, ToJson
80-
81-
/-- Internal success payload for direct-import queries from the current tracked text snapshot. -/
82-
structure DirectImportsResult where
83-
version : Nat
84-
imports : Array String := #[]
85-
deriving FromJson, ToJson
86-
87-
end RunAt.Internal
15+
- `RunAt.Internal.SaveSupport` for the supported save-after-sync broker path
16+
- `RunAt.Internal.DirectImports` for the unsupported direct-import query path
17+
-/

0 commit comments

Comments
 (0)