prosgarz35 commented on PR #3198:
URL: https://github.com/apache/james-project/pull/3198#issuecomment-5807081423

       ### [IMAP] IDLE hardening: transport liveness checks, idempotent 
cleanup, and reactive teardown
   
       #### Context & Motivation
       Following community review on IMAP IDLE stability, several edge cases 
and race conditions were identified and addressed:
       1. **False-positive disconnects on quiet IDLE sessions**:
          Configuring `READER_IDLE` in Netty's `ImapIdleStateHandler` risked 
disconnecting healthy RFC 2177 clients that remain silent while waiting for 
server pushes and receiving server heartbeats.
       2. **Double `popLineHandler()` race condition**:
          Independent unregistration logic across the line handler, periodic 
heartbeat failure handlers, and session errors could potentially invoke 
`session.popLineHandler()` more than once, popping unintended downstream 
handlers from
     the session stack.
       3. **Fire-and-forget `LOGOUT`**:
          Invoking `.subscribe()` on `session.logout()` inside a continuation 
line handler bypassed Reactor's backpressure and error propagation mechanisms.
       4. **Stale resources on push delivery failures**:
          When an unsolicited event update failed during write (e.g. broken 
pipe / client abruptly severed connection), the error was logged, but IDLE 
state and recurring heartbeat tasks could linger.
       5. **Unselected IDLE completion**:
          In `AUTHENTICATED` state without a selected mailbox (`sm == null`), 
the readiness sink lacked an immediate completion signal.
   
       #### Key Changes
       - **Preserved `ALL_IDLE` in `ImapIdleStateHandler`**:
         Reverted to standard `ALL_IDLE` handling to ensure valid, silent IDLE 
sessions receiving heartbeats are never terminated prematurely. Connection 
liveness is instead managed cleanly via `channel.isActive()`.
       - **Introduced `ImapSession#isConnected()`**:
         Added default non-breaking method `isConnected()` to `ImapSession` 
(backed by `channel.isActive()` in `NettyImapSession`). Used by `IdleProcessor` 
to abort heartbeats and continuation processing on dropped connections.
       - **Idempotent Atomic Cleanup (`cleanupIdle`)**:
         Consolidated mailbox listener unregistration and 
`session.popLineHandler()` inside `cleanupIdle(...)` guarded by an atomic CAS 
(`idleActive.compareAndSet(true, false)`). Ensures teardown runs strictly once 
across concurrent
     `DONE`, timeout, push failure, or error paths.
       - **Managed Reactive Pipeline for mid-IDLE `LOGOUT`**:
         Continuation line handler returns `session1.logout()` directly as part 
of the `Mono<Void>` pipeline rather than calling detached `.subscribe()`.
       - **Immediate Push Error Teardown**:
         `IdleMailboxListener#reactiveEvent` now triggers `cleanupIdle(...)` 
upon write errors, immediately halting heartbeats and removing stale listeners.
       - **Immediate Readiness for Unselected IDLE**:
         Added immediate `idleReadySink.tryEmitEmpty()` when `sm == null` (RFC 
2177 unselected IDLE).
   
       #### Verification
       - Backward compatibility: 100% preserved (all public APIs intact, 
default methods provide seamless interop).
       - Modules `:protocols-imap` and `:james-server-protocols-imap4` compile 
cleanly with Maven 3.9+ and OpenJDK.
       - Checkstyle: **0 violations**.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to