Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit595c010

Browse files
committed
use a log file for daemon
1 parent4689f22 commit595c010

File tree

6 files changed

+39
-159
lines changed

6 files changed

+39
-159
lines changed

‎Coder-Desktop/Coder-Desktop/Preview Content/PreviewFileSync.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import VPNLib
22

33
@MainActor
44
finalclassPreviewFileSync:FileSyncDaemon{
5+
varlogFile:URL=.init(filePath:"~/log.txt")!
6+
57
varsessionState:[VPNLib.FileSyncSession]=[]
68

79
varstate:DaemonState=.running
810

9-
varrecentLogs:[String]=[]
10-
1111
init(){}
1212

1313
func refreshSessions()async{}

‎Coder-Desktop/Coder-Desktop/Views/FileSync/FileSyncConfig.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,12 @@ struct FileSyncConfig<VPN: VPNService, FS: FileSyncDaemon>: View {
8686
dontRetry=true
8787
}
8888
} message:{
89-
// You can't have styled text in alert messages
9089
Text("""
91-
File sync daemon failed:\(fileSync.state.description)\n\n\(fileSync.recentLogs.joined(separator:"\n"))
92-
""")
90+
File sync daemon failed. The daemon log file at\n\(fileSync.logFile.path)\nhas been opened.
91+
""").onAppear{
92+
// Open the log file in the default editor
93+
NSWorkspace.shared.open(fileSync.logFile)
94+
}
9395
}.task{
9496
// When the Window is visible, poll for session updates every
9597
// two seconds.

‎Coder-Desktop/Coder-DesktopTests/Util.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ class MockVPNService: VPNService, ObservableObject {
2929

3030
@MainActor
3131
classMockFileSyncDaemon:FileSyncDaemon{
32+
varlogFile:URL=.init(filePath:"~/log.txt")
33+
3234
varsessionState:[VPNLib.FileSyncSession]=[]
3335

3436
func refreshSessions()async{}
3537

36-
varrecentLogs:[String]=[]
37-
3838
func deleteSessions(ids _:[String])asyncthrows(VPNLib.DaemonError){}
3939

4040
varstate:VPNLib.DaemonState=.running

‎Coder-Desktop/VPNLib/FileSync/FileSyncDaemon.swift

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import SwiftUI
1010
publicprotocolFileSyncDaemon:ObservableObject{
1111
varstate:DaemonState{get}
1212
varsessionState:[FileSyncSession]{get}
13-
varrecentLogs:[String]{get}
13+
varlogFile:URL{get}
1414
func tryStart()async
1515
func stop()async
1616
func refreshSessions()async
@@ -39,15 +39,13 @@ public class MutagenDaemon: FileSyncDaemon {
3939

4040
@PublishedpublicvarsessionState:[FileSyncSession]=[]
4141

42-
// We store the last N log lines to show in the UI if the daemon crashes
43-
privatevarlogBuffer:RingBuffer<String>
44-
publicvarrecentLogs:[String]{ logBuffer.elements}
45-
4642
privatevarmutagenProcess:Subprocess?
4743
privateletmutagenPath:URL!
4844
privateletmutagenDataDirectory:URL
4945
privateletmutagenDaemonSocket:URL
5046

47+
publicletlogFile:URL
48+
5149
// Managing sync sessions could take a while, especially with prompting
5250
letsessionMgmtReqTimeout:TimeAmount=.seconds(15)
5351

@@ -64,13 +62,12 @@ public class MutagenDaemon: FileSyncDaemon {
6462
mutagenDataDirectory:URL=FileManager.default.urls(
6563
for:.applicationSupportDirectory,
6664
in:.userDomainMask
67-
).first!.appending(path:"Coder Desktop").appending(path:"Mutagen"),
68-
logBufferCapacity:Int=10)
65+
).first!.appending(path:"Coder Desktop").appending(path:"Mutagen"))
6966
{
70-
logBuffer=.init(capacity: logBufferCapacity)
7167
self.mutagenPath= mutagenPath
7268
self.mutagenDataDirectory= mutagenDataDirectory
7369
mutagenDaemonSocket= mutagenDataDirectory.appending(path:"daemon").appending(path:"daemon.sock")
70+
logFile= mutagenDataDirectory.appending(path:"daemon.log")
7471
// It shouldn't be fatal if the app was built without Mutagen embedded,
7572
// but file sync will be unavailable.
7673
if mutagenPath==nil{
@@ -113,34 +110,23 @@ public class MutagenDaemon: FileSyncDaemon {
113110

114111
// Creating the same process twice from Swift will crash the MainActor,
115112
// so we need to wait for an earlier process to die
116-
iflet waitForExit{
117-
awaitwaitForExit()
118-
// We *need* to be sure the process is dead or the app ends up in an
119-
// unrecoverable state
120-
try?awaitTask.sleep(for:.seconds(1))
121-
}
113+
awaitwaitForExit?()
122114

123115
await transition.wait()
124116
defer{ transition.signal()}
125117
logger.info("starting mutagen daemon")
126118

127119
mutagenProcess=createMutagenProcess()
128-
// swiftlint:disable:next large_tuple
129-
let(standardOutput, standardError, waitForExit):(Pipe.AsyncBytes,Pipe.AsyncBytes,@Sendable()async->Void)
120+
let(standardError, waitForExit):(Pipe.AsyncBytes,@Sendable()async->Void)
130121
do{
131-
(standardOutput, standardError, waitForExit)=try mutagenProcess!.run()
122+
(_, standardError, waitForExit)=try mutagenProcess!.run()
132123
}catch{
133124
throw.daemonStartFailure(error)
134125
}
135126
self.waitForExit= waitForExit
136127

137128
Task{
138-
awaitstreamHandler(io: standardOutput)
139-
logger.info("standard output stream closed")
140-
}
141-
142-
Task{
143-
awaitstreamHandler(io: standardError)
129+
awaithandleDaemonLogs(io: standardError)
144130
logger.info("standard error stream closed")
145131
}
146132

@@ -283,11 +269,30 @@ public class MutagenDaemon: FileSyncDaemon {
283269
}
284270
}
285271

286-
privatefunc streamHandler(io:Pipe.AsyncBytes)async{
272+
privatefunc handleDaemonLogs(io:Pipe.AsyncBytes)async{
273+
if !FileManager.default.fileExists(atPath: logFile.path){
274+
guardFileManager.default.createFile(atPath: logFile.path, contents:nil)else{
275+
logger.error("Failed to create log file")
276+
return
277+
}
278+
}
279+
280+
guardlet fileHandle=try?FileHandle(forWritingTo: logFile)else{
281+
logger.error("Failed to open log file for writing")
282+
return
283+
}
284+
287285
forawaitlinein io.lines{
288286
logger.info("\(line, privacy:.public)")
289-
logBuffer.append(line)
287+
288+
do{
289+
try fileHandle.write(contentsOf:Data("\(line)\n".utf8))
290+
}catch{
291+
logger.error("Failed to write to daemon log file:\(error)")
292+
}
290293
}
294+
295+
try? fileHandle.close()
291296
}
292297
}
293298

‎Coder-Desktop/VPNLib/Util.swift

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,39 +29,3 @@ public func makeNSError(suffix: String, code: Int = -1, desc: String) -> NSError
2929
userInfo:[NSLocalizedDescriptionKey: desc]
3030
)
3131
}
32-
33-
// Insertion-only RingBuffer for buffering the last `capacity` elements,
34-
// and retrieving them in insertion order.
35-
publicstructRingBuffer<T>{
36-
privatevarbuffer:[T?]
37-
privatevarstart=0
38-
privatevarsize=0
39-
40-
publicinit(capacity:Int){
41-
buffer=Array(repeating:nil, count: capacity)
42-
}
43-
44-
publicmutatingfunc append(_ element:T){
45-
letwriteIndex=(start+ size)% buffer.count
46-
buffer[writeIndex]= element
47-
48-
if size< buffer.count{
49-
size+=1
50-
}else{
51-
start=(start+1)% buffer.count
52-
}
53-
}
54-
55-
publicvarelements:[T]{
56-
varresult=[T]()
57-
result.reserveCapacity(size)
58-
foriin0..< size{
59-
letindex=(start+ i)% buffer.count
60-
iflet element=buffer[index]{
61-
result.append(element)
62-
}
63-
}
64-
65-
return result
66-
}
67-
}

‎Coder-Desktop/VPNLibTests/UtilTests.swift

Lines changed: 0 additions & 91 deletions
This file was deleted.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp