From 1e3dc61697a36098e9fa4e7a0677bda60ebfd7ef Mon Sep 17 00:00:00 2001 From: LosFarmosCTL <80157503+LosFarmosCTL@users.noreply.github.com> Date: Mon, 22 Jan 2024 07:31:31 +0100 Subject: [PATCH] fix: remove completed continuations from the connections list --- .../AuthenticationContinuation.swift | 34 ++++++++----- .../CapabilitiesContinuation.swift | 6 ++- .../JoinContinuation.swift | 51 +++++++++++-------- .../PartContinuation.swift | 8 +-- .../TwitchContinuation.swift | 2 +- .../Twitch/Chat/IRC/TwitchIRCConnection.swift | 9 +++- 6 files changed, 70 insertions(+), 40 deletions(-) diff --git a/Sources/Twitch/Chat/IRC/TwitchContinuations/AuthenticationContinuation.swift b/Sources/Twitch/Chat/IRC/TwitchContinuations/AuthenticationContinuation.swift index f8cb210..5ed2c89 100644 --- a/Sources/Twitch/Chat/IRC/TwitchContinuations/AuthenticationContinuation.swift +++ b/Sources/Twitch/Chat/IRC/TwitchContinuations/AuthenticationContinuation.swift @@ -3,18 +3,28 @@ import TwitchIRC internal actor AuthenticationContinuation: TwitchContinuation { private var continuation: CheckedContinuation? - internal func check(message: IncomingMessage) async { - if case .connectionNotice = message { - continuation?.resume() - continuation = nil - } else if case .notice(let notice) = message { - if case .global(let message) = notice.kind { - if message.contains("Login authentication failed") { - continuation?.resume(throwing: IRCError.loginFailed) - continuation = nil - } - } - } + internal func check(message: IncomingMessage) async -> Bool { + return checkConnectionNotice(message: message) + || checkNotice(message: message) + } + + private func checkConnectionNotice(message: IncomingMessage) -> Bool { + guard case .connectionNotice = message else { return false } + + continuation?.resume() + continuation = nil + return true + } + + private func checkNotice(message: IncomingMessage) -> Bool { + guard case .notice(let notice) = message else { return false } + guard case .global(let message) = notice.kind else { return false } + + guard message.contains("Login authentication failed") else { return false } + + continuation?.resume(throwing: IRCError.loginFailed) + continuation = nil + return true } internal init(_ continuation: CheckedContinuation) { diff --git a/Sources/Twitch/Chat/IRC/TwitchContinuations/CapabilitiesContinuation.swift b/Sources/Twitch/Chat/IRC/TwitchContinuations/CapabilitiesContinuation.swift index d6e5fc9..56ea6f8 100644 --- a/Sources/Twitch/Chat/IRC/TwitchContinuations/CapabilitiesContinuation.swift +++ b/Sources/Twitch/Chat/IRC/TwitchContinuations/CapabilitiesContinuation.swift @@ -3,11 +3,13 @@ import TwitchIRC internal actor CapabilitiesContinuation: TwitchContinuation { private var continuation: CheckedContinuation? - internal func check(message: IncomingMessage) async { - guard case .capabilities = message else { return } + internal func check(message: IncomingMessage) async -> Bool { + guard case .capabilities = message else { return false } continuation?.resume() continuation = nil + + return true } internal init(_ continuation: CheckedContinuation) { diff --git a/Sources/Twitch/Chat/IRC/TwitchContinuations/JoinContinuation.swift b/Sources/Twitch/Chat/IRC/TwitchContinuations/JoinContinuation.swift index ef4f566..017966e 100644 --- a/Sources/Twitch/Chat/IRC/TwitchContinuations/JoinContinuation.swift +++ b/Sources/Twitch/Chat/IRC/TwitchContinuations/JoinContinuation.swift @@ -4,27 +4,38 @@ internal actor JoinContinuation: TwitchContinuation { private var continuation: CheckedContinuation? private let channel: String - internal func check(message: IncomingMessage) async { - if case .join(let join) = message { - if join.channel == self.channel { - continuation?.resume() - continuation = nil - } - } else if case .notice(let notice) = message { - if case .local(let channel, _, let noticeId) = notice.kind { - if case .msgChannelSuspended = noticeId { - if channel == self.channel { - continuation?.resume(throwing: IRCError.channelSuspended(channel)) - continuation = nil - } - } else if case .msgBanned = noticeId { - if channel == self.channel { - continuation?.resume(throwing: IRCError.bannedFromChannel(channel)) - continuation = nil - } - } - } + internal func check(message: IncomingMessage) async -> Bool { + return checkNotice(message: message) || checkJoin(message: message) + } + + private func checkNotice(message: IncomingMessage) -> Bool { + guard case .notice(let notice) = message else { return false } + guard case .local(let channel, _, let noticeId) = notice.kind else { + return false + } + + guard channel == self.channel else { return false } + + switch noticeId { + case .msgChannelSuspended: + continuation?.resume(throwing: IRCError.channelSuspended(channel)) + case .msgBanned: + continuation?.resume(throwing: IRCError.bannedFromChannel(channel)) + default: return false } + + continuation = nil + return true + } + + private func checkJoin(message: IncomingMessage) -> Bool { + guard case .join(let join) = message else { return false } + guard join.channel == self.channel else { return false } + + continuation?.resume() + continuation = nil + + return true } internal init( diff --git a/Sources/Twitch/Chat/IRC/TwitchContinuations/PartContinuation.swift b/Sources/Twitch/Chat/IRC/TwitchContinuations/PartContinuation.swift index 9895e40..2a439d2 100644 --- a/Sources/Twitch/Chat/IRC/TwitchContinuations/PartContinuation.swift +++ b/Sources/Twitch/Chat/IRC/TwitchContinuations/PartContinuation.swift @@ -4,12 +4,14 @@ internal actor PartContinuation: TwitchContinuation { private var continuation: CheckedContinuation? private let channel: String - internal func check(message: IncomingMessage) async { - guard case .part(let part) = message else { return } - guard part.channel == self.channel else { return } + internal func check(message: IncomingMessage) async -> Bool { + guard case .part(let part) = message else { return false } + guard part.channel == self.channel else { return false } continuation?.resume() continuation = nil + + return true } internal init( diff --git a/Sources/Twitch/Chat/IRC/TwitchContinuations/TwitchContinuation.swift b/Sources/Twitch/Chat/IRC/TwitchContinuations/TwitchContinuation.swift index 7b9a09d..41b4bed 100644 --- a/Sources/Twitch/Chat/IRC/TwitchContinuations/TwitchContinuation.swift +++ b/Sources/Twitch/Chat/IRC/TwitchContinuations/TwitchContinuation.swift @@ -1,5 +1,5 @@ import TwitchIRC internal protocol TwitchContinuation { - func check(message: IncomingMessage) async + func check(message: IncomingMessage) async -> Bool } diff --git a/Sources/Twitch/Chat/IRC/TwitchIRCConnection.swift b/Sources/Twitch/Chat/IRC/TwitchIRCConnection.swift index 03e1486..5f79286 100644 --- a/Sources/Twitch/Chat/IRC/TwitchIRCConnection.swift +++ b/Sources/Twitch/Chat/IRC/TwitchIRCConnection.swift @@ -125,8 +125,13 @@ internal class TwitchIRCConnection { // TODO: check all other NOTICE cases that indicate failure private func checkContinuations(with message: IncomingMessage) async { - for continuation in continuations { - await continuation.check(message: message) + var incompleteContinuations: [TwitchContinuation] = [] + + for continuation in continuations + where await !continuation.check(message: message) { + incompleteContinuations.append(continuation) } + + continuations = incompleteContinuations } }