Skip to content

Commit 8b338a2

Browse files
chore: gracefully shutdown app (#25)
1 parent 7e37b0e commit 8b338a2

File tree

4 files changed

+69
-25
lines changed

4 files changed

+69
-25
lines changed

Diff for: Coder Desktop/Coder Desktop/Coder_DesktopApp.swift

+8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
3737
}
3838
}
3939

40+
func applicationShouldTerminate(_: NSApplication) -> NSApplication.TerminateReply {
41+
Task {
42+
await vpn.stop()
43+
NSApp.reply(toApplicationShouldTerminate: true)
44+
}
45+
return .terminateLater
46+
}
47+
4048
func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool {
4149
false
4250
}

Diff for: Coder Desktop/Coder Desktop/Preview Content/PreviewVPN.swift

+31-12
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,46 @@ final class PreviewVPN: Coder_Desktop.VPNService {
2424
self.shouldFail = shouldFail
2525
}
2626

27+
var startTask: Task<Void, Never>?
2728
func start() async {
28-
state = .connecting
29-
do {
30-
try await Task.sleep(for: .seconds(10))
31-
} catch {
32-
state = .failed(.longTestError)
29+
if await startTask?.value != nil {
3330
return
3431
}
35-
state = shouldFail ? .failed(.longTestError) : .connected
32+
33+
startTask = Task {
34+
state = .connecting
35+
do {
36+
try await Task.sleep(for: .seconds(5))
37+
} catch {
38+
state = .failed(.longTestError)
39+
return
40+
}
41+
state = shouldFail ? .failed(.longTestError) : .connected
42+
}
43+
defer { startTask = nil }
44+
await startTask?.value
3645
}
3746

47+
var stopTask: Task<Void, Never>?
3848
func stop() async {
49+
await startTask?.value
3950
guard state == .connected else { return }
40-
state = .disconnecting
41-
do {
42-
try await Task.sleep(for: .seconds(10))
43-
} catch {
44-
state = .failed(.longTestError)
51+
if await stopTask?.value != nil {
4552
return
4653
}
47-
state = .disabled
54+
55+
stopTask = Task {
56+
state = .disconnecting
57+
do {
58+
try await Task.sleep(for: .seconds(5))
59+
} catch {
60+
state = .failed(.longTestError)
61+
return
62+
}
63+
state = .disabled
64+
}
65+
defer { stopTask = nil }
66+
await stopTask?.value
4867
}
4968

5069
func configureTunnelProviderProtocol(proto _: NETunnelProviderProtocol?) {

Diff for: Coder Desktop/Coder Desktop/VPNService.swift

+29-9
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,40 @@ final class CoderVPNService: NSObject, VPNService {
6868
installSystemExtension()
6969
}
7070

71+
var startTask: Task<Void, Never>?
7172
func start() async {
72-
tunnelState = .connecting
73-
await enableNetworkExtension()
73+
if await startTask?.value != nil {
74+
return
75+
}
76+
startTask = Task {
77+
tunnelState = .connecting
78+
await enableNetworkExtension()
7479

75-
// TODO: enable communication with the NetworkExtension to track state and agents. For
76-
// now, just pretend it worked...
77-
tunnelState = .connected
80+
// TODO: enable communication with the NetworkExtension to track state and agents. For
81+
// now, just pretend it worked...
82+
tunnelState = .connected
83+
}
84+
defer { startTask = nil }
85+
await startTask?.value
7886
}
7987

88+
var stopTask: Task<Void, Never>?
8089
func stop() async {
81-
tunnelState = .disconnecting
82-
await disableNetworkExtension()
83-
// TODO: determine when the NetworkExtension is completely disconnected
84-
tunnelState = .disabled
90+
// Wait for a start operation to finish first
91+
await startTask?.value
92+
guard state == .connected else { return }
93+
if await stopTask?.value != nil {
94+
return
95+
}
96+
stopTask = Task {
97+
tunnelState = .disconnecting
98+
await disableNetworkExtension()
99+
100+
// TODO: determine when the NetworkExtension is completely disconnected
101+
tunnelState = .disabled
102+
}
103+
defer { stopTask = nil }
104+
await stopTask?.value
85105
}
86106

87107
func configureTunnelProviderProtocol(proto: NETunnelProviderProtocol?) {

Diff for: Coder Desktop/Coder Desktop/Views/VPNMenu.swift

+1-4
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ struct VPNMenu<VPN: VPNService, S: Session>: View {
5959
}.buttonStyle(.plain)
6060
TrayDivider()
6161
Button {
62-
Task {
63-
await vpn.stop()
64-
NSApp.terminate(nil)
65-
}
62+
NSApp.terminate(nil)
6663
} label: {
6764
ButtonRowView {
6865
Text("Quit")

0 commit comments

Comments
 (0)