diff options
| author | Andrew Bulhak <andrew.bulhak@mullvad.net> | 2024-05-24 15:55:19 +0200 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2024-05-29 13:40:11 +0200 |
| commit | b26e90d1cd8bcf2730e1238656f907330d33f773 (patch) | |
| tree | 22c7675413b4c5fef74a8f8e64d942fc2935659c | |
| parent | 12ad692b7f423b9fa1474b14bf4ce6ed5bf4cc91 (diff) | |
| download | mullvadvpn-b26e90d1cd8bcf2730e1238656f907330d33f773.tar.xz mullvadvpn-b26e90d1cd8bcf2730e1238656f907330d33f773.zip | |
Rename occurrences of Command to Event, for accuracy
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/project.pbxproj | 16 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/EventChannel.swift (renamed from ios/PacketTunnelCore/Actor/CommandChannel.swift) | 55 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActor+ConnectionMonitoring.swift | 4 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift | 2 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActor+KeyPolicy.swift | 4 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActor+NetworkReachability.swift | 4 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActor+PostQuantum.swift | 2 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActor+Public.swift | 12 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActor.swift | 32 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActorCommand.swift | 4 | ||||
| -rw-r--r-- | ios/PacketTunnelCore/Actor/PacketTunnelActorReducer.swift | 8 | ||||
| -rw-r--r-- | ios/PacketTunnelCoreTests/EventChannelTests.swift (renamed from ios/PacketTunnelCoreTests/CommandChannelTests.swift) | 35 |
12 files changed, 90 insertions, 88 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index ef3edd54f1..8e0a798948 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -112,7 +112,7 @@ 583832252AC318A100EA2071 /* PacketTunnelActor+ConnectionMonitoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583832242AC318A100EA2071 /* PacketTunnelActor+ConnectionMonitoring.swift */; }; 583832272AC3193600EA2071 /* PacketTunnelActor+SleepCycle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583832262AC3193600EA2071 /* PacketTunnelActor+SleepCycle.swift */; }; 583832292AC3DF1300EA2071 /* PacketTunnelActorCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583832282AC3DF1300EA2071 /* PacketTunnelActorCommand.swift */; }; - 5838322B2AC3EF9600EA2071 /* CommandChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5838322A2AC3EF9600EA2071 /* CommandChannel.swift */; }; + 5838322B2AC3EF9600EA2071 /* EventChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5838322A2AC3EF9600EA2071 /* EventChannel.swift */; }; 583D86482A2678DC0060D63B /* DeviceStateAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583D86472A2678DC0060D63B /* DeviceStateAccessor.swift */; }; 583DA21425FA4B5C00318683 /* LocationDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583DA21325FA4B5C00318683 /* LocationDataSource.swift */; }; 583FE01029C0F532006E85F9 /* CustomSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583FE00F29C0F532006E85F9 /* CustomSplitViewController.swift */; }; @@ -170,7 +170,7 @@ 586C0D932B03D90700E7CDD7 /* ShadowsocksItemIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586C0D922B03D90700E7CDD7 /* ShadowsocksItemIdentifier.swift */; }; 586C0D952B03D92100E7CDD7 /* SocksItemIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586C0D942B03D92100E7CDD7 /* SocksItemIdentifier.swift */; }; 586C0D992B04E20200E7CDD7 /* AccessMethodViewModel+Persistent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586C0D982B04E20200E7CDD7 /* AccessMethodViewModel+Persistent.swift */; }; - 586C14582AC463BB00245C01 /* CommandChannelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586C14572AC463BB00245C01 /* CommandChannelTests.swift */; }; + 586C14582AC463BB00245C01 /* EventChannelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586C14572AC463BB00245C01 /* EventChannelTests.swift */; }; 586C145A2AC4735F00245C01 /* PacketTunnelActor+Public.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586C14592AC4735F00245C01 /* PacketTunnelActor+Public.swift */; }; 586E54FB27A2DF6D0029B88B /* SendTunnelProviderMessageOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586E54FA27A2DF6D0029B88B /* SendTunnelProviderMessageOperation.swift */; }; 586E8DB82AAF4AC4007BF3DA /* Task+Duration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586E8DB72AAF4AC4007BF3DA /* Task+Duration.swift */; }; @@ -1507,7 +1507,7 @@ 583832242AC318A100EA2071 /* PacketTunnelActor+ConnectionMonitoring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PacketTunnelActor+ConnectionMonitoring.swift"; sourceTree = "<group>"; }; 583832262AC3193600EA2071 /* PacketTunnelActor+SleepCycle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PacketTunnelActor+SleepCycle.swift"; sourceTree = "<group>"; }; 583832282AC3DF1300EA2071 /* PacketTunnelActorCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelActorCommand.swift; sourceTree = "<group>"; }; - 5838322A2AC3EF9600EA2071 /* CommandChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandChannel.swift; sourceTree = "<group>"; }; + 5838322A2AC3EF9600EA2071 /* EventChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventChannel.swift; sourceTree = "<group>"; }; 583D86472A2678DC0060D63B /* DeviceStateAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceStateAccessor.swift; sourceTree = "<group>"; }; 583DA21325FA4B5C00318683 /* LocationDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationDataSource.swift; sourceTree = "<group>"; }; 583E1E292848DF67004838B3 /* OperationObserverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationObserverTests.swift; sourceTree = "<group>"; }; @@ -1577,7 +1577,7 @@ 586C0D942B03D92100E7CDD7 /* SocksItemIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocksItemIdentifier.swift; sourceTree = "<group>"; }; 586C0D962B04E0AC00E7CDD7 /* PersistentAccessMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistentAccessMethod.swift; sourceTree = "<group>"; }; 586C0D982B04E20200E7CDD7 /* AccessMethodViewModel+Persistent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccessMethodViewModel+Persistent.swift"; sourceTree = "<group>"; }; - 586C14572AC463BB00245C01 /* CommandChannelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandChannelTests.swift; sourceTree = "<group>"; }; + 586C14572AC463BB00245C01 /* EventChannelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventChannelTests.swift; sourceTree = "<group>"; }; 586C14592AC4735F00245C01 /* PacketTunnelActor+Public.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PacketTunnelActor+Public.swift"; sourceTree = "<group>"; }; 586E54FA27A2DF6D0029B88B /* SendTunnelProviderMessageOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendTunnelProviderMessageOperation.swift; sourceTree = "<group>"; }; 586E7A2C2A987689006DAB1B /* SettingsReaderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsReaderProtocol.swift; sourceTree = "<group>"; }; @@ -3093,7 +3093,7 @@ 58BDEBA02A9CA14B00F578F2 /* AnyTask.swift */, 58F3F3652AA086A400D3B0A4 /* AutoCancellingTask.swift */, 583832282AC3DF1300EA2071 /* PacketTunnelActorCommand.swift */, - 5838322A2AC3EF9600EA2071 /* CommandChannel.swift */, + 5838322A2AC3EF9600EA2071 /* EventChannel.swift */, 583E60952A9F6D0800DC61EF /* ConfigurationBuilder.swift */, 580D6B892AB31AB400B2D6E0 /* NetworkPath+NetworkReachability.swift */, 58CF95A12AD6F35800B59F5D /* ObservedState.swift */, @@ -3370,7 +3370,7 @@ children = ( 58EC067D2A8D2B0700BEB973 /* Mocks */, 7A3FD1B42AD4465A0042BEA6 /* AppMessageHandlerTests.swift */, - 586C14572AC463BB00245C01 /* CommandChannelTests.swift */, + 586C14572AC463BB00245C01 /* EventChannelTests.swift */, 58FE25D32AA729B5003D1918 /* PacketTunnelActorTests.swift */, 58C7A46F2A8649ED0060C66F /* PingerTests.swift */, 5838321C2AC1C54600EA2071 /* TaskSleepTests.swift */, @@ -5498,7 +5498,7 @@ 7AD0AA1D2AD6A86700119E10 /* PacketTunnelActorProtocol.swift in Sources */, 5826B6CB2ABD83E200B1CA13 /* PacketTunnelOptions.swift in Sources */, 586E8DB82AAF4AC4007BF3DA /* Task+Duration.swift in Sources */, - 5838322B2AC3EF9600EA2071 /* CommandChannel.swift in Sources */, + 5838322B2AC3EF9600EA2071 /* EventChannel.swift in Sources */, 586C145A2AC4735F00245C01 /* PacketTunnelActor+Public.swift in Sources */, 58342C042AAB61FB003BA12D /* State+Extensions.swift in Sources */, A95EEE382B722DFC00A8A39B /* PingStats.swift in Sources */, @@ -5516,7 +5516,7 @@ files = ( 7AD0AA1C2AD6A63F00119E10 /* PacketTunnelActorStub.swift in Sources */, 58EC067A2A8D208D00BEB973 /* TunnelDeviceInfoStub.swift in Sources */, - 586C14582AC463BB00245C01 /* CommandChannelTests.swift in Sources */, + 586C14582AC463BB00245C01 /* EventChannelTests.swift in Sources */, 58EC067C2A8D2A0B00BEB973 /* NetworkCounters.swift in Sources */, 58FE25EC2AA77639003D1918 /* TunnelMonitorStub.swift in Sources */, 7A3FD1B82AD54AE60042BEA6 /* TimeServerProxy.swift in Sources */, diff --git a/ios/PacketTunnelCore/Actor/CommandChannel.swift b/ios/PacketTunnelCore/Actor/EventChannel.swift index e159100c34..a5aedcb198 100644 --- a/ios/PacketTunnelCore/Actor/CommandChannel.swift +++ b/ios/PacketTunnelCore/Actor/EventChannel.swift @@ -1,9 +1,10 @@ // -// CommandChannel.swift +// EventChannel.swift // PacketTunnelCore // // Created by pronebird on 27/09/2023. // Copyright © 2023 Mullvad VPN AB. All rights reserved. +// Formerly known as CommandChannel // import Foundation @@ -11,8 +12,8 @@ import Foundation /** Sync-to-async ordered coalescing channel with unbound buffering. - Publishers send commands over the channel to pass work to consumer. Received commands are buffered, until requested by consumer and coalesced just - before consumption. + Publishers send events over the channel to pass work to consumer. Received events + are buffered, until requested by consumer and coalesced just before consumption. - Multiple consumers are possible but the actor is really expected to be the only consumer. - Internally, the channel acquires a lock, so you can assume FIFO ordering unless you publish values simultaneously from multiple concurrent queues. @@ -20,17 +21,17 @@ import Foundation ### Example ``` - let channel = CommandChannel() + let channel = EventChannel() channel.send(.stop) ``` - Consuming commands can be implemented using a for-await loop. Note that using a loop should also serialize the command handling as the next command will not + Consuming events can be implemented using a for-await loop. Note that using a loop should also serialize the event handling as the next event will not be consumed until the body of the loop completes the iteration. ``` Task.detached { - for await command in channel { - await handleMyCommand(command) + for await event in channel { + await handleMyEvent(event) } } ``` @@ -42,14 +43,14 @@ import Foundation channel.send(.stop) channel.sendEnd() - let allReceivedCommands = channel + let allReceivedEvents = channel .map { "\($0)" } .reduce(into: [String]()) { $0.append($1) } ``` */ extension PacketTunnelActor { - final class CommandChannel: @unchecked Sendable { - typealias Command = PacketTunnelActor.Command + final class EventChannel: @unchecked Sendable { + typealias Event = PacketTunnelActor.Event private enum State { /// Channel is active and running. case active @@ -64,12 +65,12 @@ extension PacketTunnelActor { case finished } - /// A buffer of commands received but not consumed yet. - private var buffer: [Command] = [] + /// A buffer of events received but not consumed yet. + private var buffer: [Event] = [] /// Async continuations awaiting to receive the new value. /// Continuations are stored here when there is no new value available for immediate delivery. - private var pendingContinuations: [CheckedContinuation<Command?, Never>] = [] + private var pendingContinuations: [CheckedContinuation<Event?, Never>] = [] private var state: State = .active private var stateLock = NSLock() @@ -81,10 +82,10 @@ extension PacketTunnelActor { finish() } - /// Send command to consumer. + /// Send event to consumer. /// - /// - Parameter value: a new command. - func send(_ value: Command) { + /// - Parameter value: a new event. + func send(_ value: Event) { stateLock.withLock { guard case .active = state else { return } @@ -112,7 +113,7 @@ extension PacketTunnelActor { } } - /// Flush buffered commands and resume all pending continuations sending them `nil` to mark the end of iteration. + /// Flush buffered events and resume all pending continuations sending them `nil` to mark the end of iteration. func finish() { stateLock.withLock { switch state { @@ -137,15 +138,15 @@ extension PacketTunnelActor { } /// Consume first message in the buffer. - /// Returns `nil` if the buffer is empty, otherwise if attempts to coalesce buffered commands before consuming the first comand in the list. - private func consumeFirst() -> Command? { + /// Returns `nil` if the buffer is empty, otherwise if attempts to coalesce buffered events before consuming the first comand in the list. + private func consumeFirst() -> Event? { guard !buffer.isEmpty else { return nil } coalesce() return buffer.removeFirst() } - /// Coalesce buffered commands to prevent future execution when the outcome is considered to be similar. + /// Coalesce buffered events to prevent future execution when the outcome is considered to be similar. /// Mutates internal `buffer`. private func coalesce() { var i = buffer.count - 1 @@ -155,14 +156,14 @@ extension PacketTunnelActor { assert(i < buffer.count) let current = buffer[i] - // Remove all preceding commands when encountered "stop". + // Remove all preceding events when encountered "stop". if case .stop = current { buffer.removeFirst(i) return } // Coalesce earlier reconnection attempts into the most recent. - // This will rearrange the command buffer but hopefully should have no side effects. + // This will rearrange the event buffer but hopefully should have no side effects. if case .reconnect = current { // Walk backwards starting with the preceding element. for j in (0 ..< i).reversed() { @@ -177,7 +178,7 @@ extension PacketTunnelActor { } } - private func next() async -> Command? { + private func next() async -> Event? { return await withCheckedContinuation { continuation in stateLock.withLock { switch state { @@ -206,12 +207,12 @@ extension PacketTunnelActor { } } -extension PacketTunnelActor.CommandChannel: AsyncSequence { - typealias Element = Command +extension PacketTunnelActor.EventChannel: AsyncSequence { + typealias Element = Event struct AsyncIterator: AsyncIteratorProtocol { - let channel: PacketTunnelActor.CommandChannel - func next() async -> Command? { + let channel: PacketTunnelActor.EventChannel + func next() async -> Event? { return await channel.next() } } diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor+ConnectionMonitoring.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor+ConnectionMonitoring.swift index 84d34d2650..aec5b94dec 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActor+ConnectionMonitoring.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor+ConnectionMonitoring.swift @@ -13,7 +13,7 @@ extension PacketTunnelActor { func setTunnelMonitorEventHandler() { tunnelMonitor.onEvent = { [weak self] event in /// Dispatch tunnel monitor events via command channel to guarantee the order of execution. - self?.commandChannel.send(.monitorEvent(event)) + self?.eventChannel.send(.monitorEvent(event)) } } @@ -51,7 +51,7 @@ extension PacketTunnelActor { private func onHandleConnectionRecovery() async { switch state { case .connecting, .reconnecting, .connected: - commandChannel.send(.reconnect(.random, reason: .connectionLoss)) + eventChannel.send(.reconnect(.random, reason: .connectionLoss)) case .initial, .disconnected, .disconnecting, .error, .negotiatingPostQuantumKey: break diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift index fd88ea94e4..8f94dd7086 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift @@ -151,7 +151,7 @@ extension PacketTunnelActor { try await Task.sleepUsingContinuousClock(for: timings.bootRecoveryPeriodicity) // Schedule task to reconnect. - commandChannel.send(.reconnect(.random)) + eventChannel.send(.reconnect(.random)) } } diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor+KeyPolicy.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor+KeyPolicy.swift index 9181a73edf..cea84d4f21 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActor+KeyPolicy.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor+KeyPolicy.swift @@ -46,7 +46,7 @@ extension PacketTunnelActor { */ func switchToCurrentKey() { if switchToCurrentKeyInner() { - commandChannel.send(.reconnect(.random)) + eventChannel.send(.reconnect(.random)) } } @@ -65,7 +65,7 @@ extension PacketTunnelActor { try await Task.sleepUsingContinuousClock(for: timings.wgKeyPropagationDelay) // Enqueue task to change key policy. - commandChannel.send(.switchKey) + eventChannel.send(.switchKey) } return AutoCancellingTask(task) diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor+NetworkReachability.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor+NetworkReachability.swift index e60a0081ff..c475e3d798 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActor+NetworkReachability.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor+NetworkReachability.swift @@ -18,11 +18,11 @@ extension PacketTunnelActor { logger.trace("Start default path observer.") defaultPathObserver.start { [weak self] networkPath in - self?.commandChannel.send(.networkReachability(networkPath)) + self?.eventChannel.send(.networkReachability(networkPath)) } if notifyObserverWithCurrentPath, let currentPath = defaultPathObserver.defaultPath { - commandChannel.send(.networkReachability(currentPath)) + eventChannel.send(.networkReachability(currentPath)) } } diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor+PostQuantum.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor+PostQuantum.swift index 53066ce437..d721f571de 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActor+PostQuantum.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor+PostQuantum.swift @@ -55,7 +55,7 @@ extension PacketTunnelActor { logger.error("Could not create connection state in PostQuantumConnect") let nextRelay: NextRelay = (state.connectionData?.selectedRelay).map { .preSelected($0) } ?? .current - commandChannel.send(.reconnect(nextRelay)) + eventChannel.send(.reconnect(nextRelay)) return } diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor+Public.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor+Public.swift index 209a6041d5..5457757327 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActor+Public.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor+Public.swift @@ -23,14 +23,14 @@ extension PacketTunnelActor { - Parameter options: start options. */ nonisolated public func start(options: StartOptions) { - commandChannel.send(.start(options)) + eventChannel.send(.start(options)) } /** Tell actor to stop the tunnel. */ nonisolated public func stop() { - commandChannel.send(.stop) + eventChannel.send(.stop) } /** @@ -39,7 +39,7 @@ extension PacketTunnelActor { - Parameter nextRelay: next relay to connect to. */ public nonisolated func reconnect(to nextRelay: NextRelay) { - commandChannel.send(.reconnect(nextRelay)) + eventChannel.send(.reconnect(nextRelay)) } /** @@ -48,7 +48,7 @@ extension PacketTunnelActor { - Parameter date: date when last key rotation took place. */ nonisolated public func notifyKeyRotation(date: Date?) { - commandChannel.send(.notifyKeyRotated(date)) + eventChannel.send(.notifyKeyRotated(date)) } /** @@ -57,13 +57,13 @@ extension PacketTunnelActor { */ nonisolated public func replacePreSharedKey(_ key: PreSharedKey, ephemeralKey: PrivateKey) { - commandChannel.send(.replaceDevicePrivateKey(key, ephemeralKey: ephemeralKey)) + eventChannel.send(.replaceDevicePrivateKey(key, ephemeralKey: ephemeralKey)) } /** Tell actor to enter error state. */ nonisolated public func setErrorState(reason: BlockedStateReason) { - commandChannel.send(.error(reason)) + eventChannel.send(.error(reason)) } } diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift index 4391fea14d..360bccb46f 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift @@ -16,13 +16,13 @@ import WireGuardKitTypes /** Packet tunnel state machine implemented as an actor. - - Actor receives commands for execution over the `CommandChannel`. + - Actor receives events for execution over the `EventChannel`. - - Commands are consumed in a detached task via for-await loop over the channel. Each command, once received, is executed in its entirety before the next - command is processed. See the implementation of `consumeCommands()` which is the central task dispatcher inside of actor. + - Events are consumed in a detached task via for-await loop over the channel. Each event, once received, is executed in its entirety before the next + event is processed. See the implementation of `consumeEvents()` which is the central task dispatcher inside of actor. - - Most of calls that actor performs suspend for a very short amount of time. `CommandChannel` proactively discards unwanted tasks as they arrive to prevent - future execution, such as repeating commands to reconnect are coalesced and all commands prior to stop are discarded entirely as the outcome would be the + - Most of calls that actor performs suspend for a very short amount of time. `EventChannel` proactively discards unwanted tasks as they arrive to prevent + future execution, such as repeating commands to reconnect are coalesced and all events prior to stop are discarded entirely as the outcome would be the same anyway. */ public actor PacketTunnelActor { @@ -47,7 +47,7 @@ public actor PacketTunnelActor { let settingsReader: SettingsReaderProtocol let protocolObfuscator: ProtocolObfuscation - nonisolated let commandChannel = CommandChannel() + nonisolated let eventChannel = EventChannel() public init( timings: PacketTunnelActorTimings, @@ -68,27 +68,27 @@ public actor PacketTunnelActor { self.settingsReader = settingsReader self.protocolObfuscator = protocolObfuscator - consumeCommands(channel: commandChannel) + consumeEvents(channel: eventChannel) } deinit { - commandChannel.finish() + eventChannel.finish() } /** - Spawn a detached task that consumes commands from the channel indefinitely until the channel is closed. - Commands are processed one at a time, so no suspensions should affect the order of execution and thus guarantee transactional execution. + Spawn a detached task that consumes events from the channel indefinitely until the channel is closed. + Events are processed one at a time, so no suspensions should affect the order of execution and thus guarantee transactional execution. - - Parameter channel: command channel. + - Parameter channel: event channel. */ - private nonisolated func consumeCommands(channel: CommandChannel) { + private nonisolated func consumeEvents(channel: EventChannel) { Task.detached { [weak self] in - for await command in channel { + for await event in channel { guard let self else { return } - self.logger.debug("Received command: \(command.logFormat())") + self.logger.debug("Received event: \(event.logFormat())") - let effects = await self.runReducer(command) + let effects = await self.runReducer(event) for effect in effects { await executeEffect(effect) @@ -124,7 +124,7 @@ public actor PacketTunnelActor { await setErrorStateInternal(with: error) } case let .reconnect(nextRelay): - commandChannel.send(.reconnect(nextRelay)) + eventChannel.send(.reconnect(nextRelay)) case .stopTunnelAdapter: do { try await tunnelAdapter.stop() diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActorCommand.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActorCommand.swift index c4bd2c314b..024431d993 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActorCommand.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActorCommand.swift @@ -10,8 +10,8 @@ import Foundation import WireGuardKitTypes extension PacketTunnelActor { - /// Describes action that actor can perform. - enum Command { + /// Describes events that the state machine handles. These can be user commands or non-user-initiated events + enum Event { /// Start tunnel. case start(StartOptions) diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActorReducer.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActorReducer.swift index 388ceee970..50379fdd63 100644 --- a/ios/PacketTunnelCore/Actor/PacketTunnelActorReducer.swift +++ b/ios/PacketTunnelCore/Actor/PacketTunnelActorReducer.swift @@ -52,8 +52,8 @@ extension PacketTunnelActor { } } - static func reducer(_ state: inout State, _ command: Command) -> [Effect] { - switch command { + static func reducer(_ state: inout State, _ event: Event) -> [Effect] { + switch event { case let .start(options): guard case .initial = state else { return [] } return [ @@ -155,7 +155,7 @@ extension PacketTunnelActor { } } - func runReducer(_ command: Command) -> [Effect] { - PacketTunnelActor.reducer(&state, command) + func runReducer(_ event: Event) -> [Effect] { + PacketTunnelActor.reducer(&state, event) } } diff --git a/ios/PacketTunnelCoreTests/CommandChannelTests.swift b/ios/PacketTunnelCoreTests/EventChannelTests.swift index 974eca29f2..b6f50b3d0a 100644 --- a/ios/PacketTunnelCoreTests/CommandChannelTests.swift +++ b/ios/PacketTunnelCoreTests/EventChannelTests.swift @@ -1,17 +1,18 @@ // -// CommandChannelTests.swift +// EventChannelTests.swift // PacketTunnelCoreTests // // Created by pronebird on 27/09/2023. // Copyright © 2023 Mullvad VPN AB. All rights reserved. +// Formerly known as CommandChannelTests // @testable import PacketTunnelCore import XCTest -final class CommandChannelTests: XCTestCase { +final class EventChannelTests: XCTestCase { func testCoalescingReconnect() async { - let channel = PacketTunnelActor.CommandChannel() + let channel = PacketTunnelActor.EventChannel() channel.send(.start(StartOptions(launchSource: .app))) channel.send(.reconnect(.random)) @@ -20,14 +21,14 @@ final class CommandChannelTests: XCTestCase { channel.send(.reconnect(.current)) channel.sendEnd() - let commands = await channel.map { $0.primitiveCommand }.collect() + let events = await channel.map { $0.primitiveCommand }.collect() - XCTAssertEqual(commands, [.start, .switchKey, .reconnect(.current)]) + XCTAssertEqual(events, [.start, .switchKey, .reconnect(.current)]) } /// Test that stops cancels all preceding tasks. func testCoalescingStop() async { - let channel = PacketTunnelActor.CommandChannel() + let channel = PacketTunnelActor.EventChannel() channel.send(.start(StartOptions(launchSource: .app))) channel.send(.reconnect(.random)) @@ -37,14 +38,14 @@ final class CommandChannelTests: XCTestCase { channel.send(.switchKey) channel.sendEnd() - let commands = await channel.map { $0.primitiveCommand }.collect() + let events = await channel.map { $0.primitiveCommand }.collect() - XCTAssertEqual(commands, [.stop, .switchKey]) + XCTAssertEqual(events, [.stop, .switchKey]) } /// Test that iterations over the finished channel yield `nil`. func testFinishFlushingUnconsumedValues() async { - let channel = PacketTunnelActor.CommandChannel() + let channel = PacketTunnelActor.EventChannel() channel.send(.stop) channel.finish() @@ -54,14 +55,14 @@ final class CommandChannelTests: XCTestCase { /// Test that the call to `finish()` ends the iteration that began prior to that. func testFinishEndsAsyncIterator() async throws { - let channel = PacketTunnelActor.CommandChannel() + let channel = PacketTunnelActor.EventChannel() let expectFinish = expectation(description: "Call to finish()") let expectEndIteration = expectation(description: "Iteration over channel should end upon call to finish()") - // Start iterating over commands in channel. The for-await loop should suspend the continuation. + // Start iterating over events in channel. The for-await loop should suspend the continuation. Task { - for await command in channel { - print(command) + for await event in channel { + print(event) } expectEndIteration.fulfill() @@ -86,13 +87,13 @@ extension AsyncSequence { } } -/// Primitive version of `Command` that can be used in tests and easily compared against. -enum PrimitiveCommand: Equatable { +/// Simplified version of `Event` that can be used in tests and easily compared against. +enum SimplifiedEvent: Equatable { case start, stop, reconnect(NextRelay), switchKey, other } -extension PacketTunnelActor.Command { - var primitiveCommand: PrimitiveCommand { +extension PacketTunnelActor.Event { + var primitiveCommand: SimplifiedEvent { switch self { case .start: return .start |
