diff --git a/Packages/MagnumOpusCore/Sources/IMAPClient/IMAPIdleClient.swift b/Packages/MagnumOpusCore/Sources/IMAPClient/IMAPIdleClient.swift index 2500c13..dd15a5e 100644 --- a/Packages/MagnumOpusCore/Sources/IMAPClient/IMAPIdleClient.swift +++ b/Packages/MagnumOpusCore/Sources/IMAPClient/IMAPIdleClient.swift @@ -67,6 +67,12 @@ public actor IMAPIdleClient { // MARK: - Connection private func connectAndLogin() async throws { + // Clean up previous connection if reconnecting + try? await channel?.close() + channel = nil + try? await group?.shutdownGracefully() + group = nil + let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) let sslContext = try NIOSSLContext(configuration: TLSConfiguration.makeClientConfiguration()) let hostname = host @@ -138,16 +144,14 @@ public actor IMAPIdleClient { // Iterative IDLE loop — avoids unbounded stack growth from recursion while !Task.isCancelled { // Swap response handler for IDLE handler + let idleTag = "IDLE1" let (stream, streamContinuation) = AsyncStream.makeStream() - let idleHandler = IMAPIdleHandler(continuation: streamContinuation) + let idleHandler = IMAPIdleHandler(continuation: streamContinuation, idleTag: idleTag) let oldHandler = try await getResponseHandler() try await pipeline.removeHandler(oldHandler).get() try await pipeline.addHandler(idleHandler).get() - let idleTag = "IDLE1" - idleHandler.setIdleTag(idleTag) - // Send IDLE command let idleCommand = TaggedCommand(tag: idleTag, command: .idleStart) channel.writeAndFlush(IMAPClientHandler.Message.part(.tagged(idleCommand)), promise: nil) diff --git a/Packages/MagnumOpusCore/Sources/IMAPClient/IMAPIdleHandler.swift b/Packages/MagnumOpusCore/Sources/IMAPClient/IMAPIdleHandler.swift index 9fc26b0..2999057 100644 --- a/Packages/MagnumOpusCore/Sources/IMAPClient/IMAPIdleHandler.swift +++ b/Packages/MagnumOpusCore/Sources/IMAPClient/IMAPIdleHandler.swift @@ -16,14 +16,11 @@ final class IMAPIdleHandler: ChannelInboundHandler, RemovableChannelHandler, @un typealias InboundIn = Response private let continuation: AsyncStream.Continuation - private var idleTag: String? + private let idleTag: String - init(continuation: AsyncStream.Continuation) { + init(continuation: AsyncStream.Continuation, idleTag: String) { self.continuation = continuation - } - - func setIdleTag(_ tag: String) { - idleTag = tag + self.idleTag = idleTag } func channelRead(context: ChannelHandlerContext, data: NIOAny) {