Skip to content

Commit 7ca5e28

Browse files
committed
chore: create & delete sync sessions over gRPC
1 parent 015cd0c commit 7ca5e28

File tree

2 files changed

+81
-46
lines changed

2 files changed

+81
-46
lines changed

Coder-Desktop/VPNLib/FileSync/FileSyncDaemon.swift

+1-46
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public class MutagenDaemon: FileSyncDaemon {
162162
// Already connected
163163
return
164164
}
165-
group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
165+
group = MultiThreadedEventLoopGroup(numberOfThreads: 2)
166166
do {
167167
channel = try GRPCChannelPool.with(
168168
target: .unixDomainSocket(mutagenDaemonSocket.path),
@@ -252,51 +252,6 @@ public class MutagenDaemon: FileSyncDaemon {
252252
logger.info("\(line, privacy: .public)")
253253
}
254254
}
255-
256-
public func refreshSessions() async {
257-
guard case .running = state else { return }
258-
// TODO: Implement
259-
}
260-
261-
public func createSession(
262-
localPath _: String,
263-
agentHost _: String,
264-
remotePath _: String
265-
) async throws(DaemonError) {
266-
if case .stopped = state {
267-
do throws(DaemonError) {
268-
try await start()
269-
} catch {
270-
state = .failed(error)
271-
throw error
272-
}
273-
}
274-
// TODO: Add session
275-
}
276-
277-
public func deleteSessions(ids _: [String]) async throws(DaemonError) {
278-
// TODO: Delete session
279-
await stopIfNoSessions()
280-
}
281-
282-
private func stopIfNoSessions() async {
283-
let sessions: Synchronization_ListResponse
284-
do {
285-
sessions = try await client!.sync.list(Synchronization_ListRequest.with { req in
286-
req.selection = .with { selection in
287-
selection.all = true
288-
}
289-
})
290-
} catch {
291-
state = .failed(.daemonStartFailure(error))
292-
return
293-
}
294-
// If there's no configured sessions, the daemon doesn't need to be running
295-
if sessions.sessionStates.isEmpty {
296-
logger.info("No sync sessions found")
297-
await stop()
298-
}
299-
}
300255
}
301256

302257
struct DaemonClient {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
public extension MutagenDaemon {
2+
func refreshSessions() async {
3+
guard case .running = state else { return }
4+
let sessions: Synchronization_ListResponse
5+
do {
6+
sessions = try await client!.sync.list(Synchronization_ListRequest.with { req in
7+
req.selection = .with { selection in
8+
selection.all = true
9+
}
10+
})
11+
} catch {
12+
state = .failed(.grpcFailure(error))
13+
return
14+
}
15+
sessionState = sessions.sessionStates.map { FileSyncSession(state: $0) }
16+
if sessionState.isEmpty {
17+
logger.info("No sync sessions found")
18+
await stop()
19+
}
20+
}
21+
22+
func createSession(
23+
localPath: String,
24+
agentHost: String,
25+
remotePath: String
26+
) async throws(DaemonError) {
27+
if case .stopped = state {
28+
do throws(DaemonError) {
29+
try await start()
30+
} catch {
31+
state = .failed(error)
32+
throw error
33+
}
34+
}
35+
let (stream, promptID) = try await host()
36+
defer { stream.cancel() }
37+
let req = Synchronization_CreateRequest.with { req in
38+
req.prompter = promptID
39+
req.specification = .with { spec in
40+
spec.alpha = .with { alpha in
41+
alpha.protocol = .local
42+
alpha.path = localPath
43+
}
44+
spec.beta = .with { beta in
45+
beta.protocol = .ssh
46+
beta.host = agentHost
47+
beta.path = remotePath
48+
}
49+
// TODO: Ingest a config from somewhere
50+
spec.configuration = Synchronization_Configuration()
51+
spec.configurationAlpha = Synchronization_Configuration()
52+
spec.configurationBeta = Synchronization_Configuration()
53+
}
54+
}
55+
do {
56+
_ = try await client!.sync.create(req)
57+
} catch {
58+
throw .grpcFailure(error)
59+
}
60+
await refreshSessions()
61+
}
62+
63+
func deleteSessions(ids: [String]) async throws(DaemonError) {
64+
// Terminating sessions does not require prompting
65+
let (stream, promptID) = try await host(allowPrompts: false)
66+
defer { stream.cancel() }
67+
guard case .running = state else { return }
68+
do {
69+
_ = try await client!.sync.terminate(Synchronization_TerminateRequest.with { req in
70+
req.prompter = promptID
71+
req.selection = .with { selection in
72+
selection.specifications = ids
73+
}
74+
})
75+
} catch {
76+
throw .grpcFailure(error)
77+
}
78+
await refreshSessions()
79+
}
80+
}

0 commit comments

Comments
 (0)