Skip to content

Conversation

@Piumal1999
Copy link

@Piumal1999 Piumal1999 commented Nov 17, 2025

Purpose

To fix wso2/api-manager#4414

Approach

Samples

N/A

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of unexpectedly terminated backend connections: added state-aware end-of-input processing with richer diagnostics, explicit state transitions and metrics updates, more aggressive connection closure when needed, and automatic propagation of I/O errors to the error handler to reduce silent failures and improve observability and reliability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

Walkthrough

Adds a public endOfInput(NHttpClientConnection) to TargetHandler that inspects protocol state, logs diagnostics, updates metrics and state to CLOSED, shuts down the connection, and conditionally forwards an internal SND_IO_ERROR to the target error handler when a response was not completed.

Changes

Cohort / File(s) Change Summary
Backend Connection Termination Handler
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetHandler.java
Added public void endOfInput(NHttpClientConnection conn) throws IOException which: reads current ProtocolState and logs diagnostics; calls informWriterError or informReaderError based on state; updates metrics (disconnected()), sets state to CLOSED, and aggressively shuts down the connection; if previous state != RESPONSE_DONE and a request message context exists, marks internal origin as ERROR_HANDLER and forwards SND_IO_ERROR to targetErrorHandler. Added JavaDoc for the method.

Sequence Diagram(s)

sequenceDiagram
    participant Backend
    participant TargetHandler
    participant Connection
    participant Metrics
    participant TargetErrorHandler

    Backend->>TargetHandler: endOfInput(conn)
    TargetHandler->>TargetHandler: read ProtocolState & previous state
    Note right of TargetHandler: log diagnostic info
    alt state is REQUEST_HEAD or REQUEST_BODY
        TargetHandler->>TargetHandler: informWriterError(conn)
    else state is RESPONSE_HEAD or RESPONSE_BODY
        TargetHandler->>TargetHandler: informReaderError(conn)
    end
    TargetHandler->>Metrics: disconnected()
    TargetHandler->>Connection: set state -> CLOSED
    TargetHandler->>Connection: shutdown/close aggressively

    alt previous state != RESPONSE_DONE and request msg ctx exists
        TargetHandler->>TargetHandler: mark internal origin = ERROR_HANDLER
        TargetHandler->>TargetErrorHandler: forward(SND_IO_ERROR, current state)
    else
        Note right of TargetHandler: no error forwarding
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I sniffed the wire where silence grew,
I checked the state, then bid adieu.
A hurried close, a ledger scored,
If response was cut, I cry "Error!" roared.
Hop, patch, and keep the pathways true.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Trigger fault sequence for forceful connection closures' accurately reflects the main change: implementing state-aware fault sequence handling in response to forceful TCP connection closures.
Description check ✅ Passed The description covers essential sections including Purpose (links to issue), Approach (fix reintroduction and error log resolution), and appropriately marks non-applicable sections, though some template sections are omitted.
Linked Issues check ✅ Passed The PR implementation successfully addresses the linked issue #4414 by handling forceful connection closures with state-aware fault sequence logic that skips execution when response is completed.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue objective: the new endOfInput method implements state-aware connection closure handling with proper error notification logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Piumal1999 Piumal1999 marked this pull request as ready for review November 17, 2025 15:10
@Piumal1999 Piumal1999 requested a review from chanikag as a code owner November 17, 2025 15:10
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89a471d and ab28b09.

📒 Files selected for processing (1)
  • modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetHandler.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetHandler.java (2)
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetContext.java (1)
  • TargetContext (34-258)
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/PassThroughConstants.java (1)
  • PassThroughConstants (19-280)
🔇 Additional comments (1)
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetHandler.java (1)

1069-1086: Add metrics update and correlation logging to endOfInput() to match the error-handling pattern in exception().

The review comment is valid. Verification confirms:

  1. endOfInput() calls shutdownConnection(conn, true) which invokes conn.shutdown() rather than conn.close(), preventing the closed() callback from being triggered and bypassing the metrics.disconnected() call at line 832.

  2. endOfInput() lacks correlation logging entirely, whereas exception() conditionally logs to correlation log when enabled (lines 1158-1160).

Since endOfInput() represents an error path (unexpected connection termination), it should mirror the telemetry pattern in exception(): add metrics.disconnected() directly and conditionally log to correlation log using logHttpRequestErrorInCorrelationLog() when PassThroughCorrelationConfigDataHolder.isEnable() is true.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ab28b09 and f3739f9.

📒 Files selected for processing (1)
  • modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetHandler.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetHandler.java (2)
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetContext.java (1)
  • TargetContext (34-258)
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/PassThroughConstants.java (1)
  • PassThroughConstants (19-280)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetHandler.java (1)

1069-1098: Move requestMsgCtx retrieval before connection shutdown.

The implementation correctly addresses the PR objectives and previous review comments (pipe notifications, metrics update). However, requestMsgCtx is retrieved at line 1088 after shutdownConnection() at line 1087, which is inconsistent with the pattern used in closed() (line 769), timeout() (line 872), and exception() (line 1102) where the message context is retrieved before any cleanup operations.

While this likely works since the context remains attached to the connection's HttpContext, moving the retrieval earlier ensures consistency and guards against potential fragility if shutdown behavior changes.

Proposed fix
     public void endOfInput(NHttpClientConnection conn) throws IOException {
 
         ProtocolState state = TargetContext.getState(conn);
+        MessageContext requestMsgCtx = TargetContext.get(conn).getRequestMsgCtx();
         log.warn("Connection ended unexpectedly" +
                 ", " + getConnectionLoggingInfo(conn) +
                 ", State: "  + state + ".");
         
         // Notify pipes based on state to prevent thread hangs
         if (state == ProtocolState.REQUEST_HEAD || state == ProtocolState.REQUEST_BODY) {
             informWriterError(conn);
         } else if (state == ProtocolState.RESPONSE_HEAD || state == ProtocolState.RESPONSE_BODY) {
             informReaderError(conn);
         }
         
         // Update metrics
         metrics.disconnected();
         
         TargetContext.updateState(conn, ProtocolState.CLOSED);
         targetConfiguration.getConnections().shutdownConnection(conn, true);
-        MessageContext requestMsgCtx = TargetContext.get(conn).getRequestMsgCtx();
         if (state != ProtocolState.RESPONSE_DONE && requestMsgCtx != null) {
             requestMsgCtx.setProperty(PassThroughConstants.INTERNAL_EXCEPTION_ORIGIN,
                     PassThroughConstants.INTERNAL_ORIGIN_ERROR_HANDLER);
             targetErrorHandler.handleError(requestMsgCtx,
                     ErrorCodes.SND_IO_ERROR,
                     "Error in Sender",
                     null,
                     state);
         }
     }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3739f9 and 16c8212.

📒 Files selected for processing (1)
  • modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/TargetHandler.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants