fix IMAPIdleHandler thread safety: pass idleTag via init, clean up event loop group on reconnect
This commit is contained in:
@@ -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<IMAPIdleEvent>.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)
|
||||
|
||||
Reference in New Issue
Block a user