Skip to content

feat(grpc-gcp): penalize retryable channel errors - #14219

Open
rahul2393 wants to merge 1 commit into
mainfrom
fm/dcp-split-4-error-penalty
Open

feat(grpc-gcp): penalize retryable channel errors#14219
rahul2393 wants to merge 1 commit into
mainfrom
fm/dcp-split-4-error-penalty

Conversation

@rahul2393

@rahul2393 rahul2393 commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

With dynamic scaling enabled, a channel returning retryable errors (UNAVAILABLE / RESOURCE_EXHAUSTED) kept its low active-stream count and so kept attracting picks: the pool had no signal that a channel was unhealthy until its streams actually piled up, and scale-up never triggered for a pool that was failing rather than busy.

Change

  • Error penalty on retryable failures. A call completing with UNAVAILABLE or RESOURCE_EXHAUSTED adds errorPenaltyStep (new pool option) of synthetic load to that channel for errorPenaltyDuration, capped at maxRpcPerChannel. The picker sees the penalty through getPickerLoad(), steering new picks toward healthy channels; expiry is lazy and lock-free.
  • Scale-up integration. Penalty load counts toward the dynamic scale-up trigger, so a pool that is failing-but-idle can still grow.
  • Single net-delta aggregate accounting. Every update to the shared penalty aggregate is computed under the channel lock and applied as one atomic delta, so lock-free readers never observe an intermediate state; a channel leaving the pool clears its contribution.
  • Negative errorPenalty duration disables the penalty

@rahul2393
rahul2393 requested review from a team as code owners August 31, 2026 17:49

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces an error penalty mechanism for channels experiencing retryable errors (such as UNAVAILABLE or RESOURCE_EXHAUSTED). It adds configuration options for the penalty step and duration, tracks individual and aggregate penalty loads, and incorporates these penalties into the channel load calculations and scale-up signaling. Additionally, a comprehensive test suite has been added to verify the correctness of the error penalty logic under various scenarios. I have no feedback to provide.

Comment on lines 2050 to 2052
if (!useDifferentChannel && channelRef != null && !channelRef.getChannel().isShutdown()) {
return channelRef;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This does not take any error penalty into account. For read/write transactions, that is maybe (probably) the right choice. But for read-only transactions, where channel affinity is just a 'nice-to-have', it is probably not the right choice.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yes but that means we need to send transaction type info here which will be beyond the scope of this PR, can be done in follow-up PR

Comment thread grpc-gcp-java/src/main/java/com/google/cloud/grpc/GcpManagedChannelOptions.java Outdated
Comment thread grpc-gcp-java/src/main/java/com/google/cloud/grpc/GcpManagedChannel.java Outdated
|| errorPenaltyDuration.isZero()
|| errorPenaltyDuration.isNegative()
|| (status.getCode() != Code.UNAVAILABLE
&& status.getCode() != Code.RESOURCE_EXHAUSTED)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we indiscriminately apply errors for all RESOURCE_EXHAUSTED errors? Or only the ones that include certain metadata? (e.g. a RetryInfo)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In design review it was agreed that we will apply for all RESOURCE_EXHAUSTED errors so want to keep same here

@rahul2393
rahul2393 force-pushed the fm/dcp-split-4-error-penalty branch 3 times, most recently from 4524b24 to 993773c Compare September 1, 2026 09:30
@rahul2393
rahul2393 requested a review from olavloite September 1, 2026 09:41

@olavloite olavloite left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, except for the configuration option setters.

(Also do a recheck whether the PR description is up to date with the implementation)

Comment thread grpc-gcp-java/src/main/java/com/google/cloud/grpc/GcpManagedChannelOptions.java Outdated
Comment thread grpc-gcp-java/src/main/java/com/google/cloud/grpc/GcpManagedChannelOptions.java Outdated
Comment thread grpc-gcp-java/src/main/java/com/google/cloud/grpc/GcpManagedChannelOptions.java Outdated
@rahul2393
rahul2393 force-pushed the fm/dcp-split-4-error-penalty branch from 993773c to f2e9cae Compare September 1, 2026 13:55
@rahul2393

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces an error penalty mechanism to the GCP Managed Channel pool. When retryable errors (such as UNAVAILABLE or RESOURCE_EXHAUSTED) occur on a channel, a decaying load penalty is applied to that channel. This penalty is added to the active stream count to compute the "picker load", which is then used by the channel selection strategies to steer traffic away from degraded channels. The PR also adds configuration options for the penalty step and duration, updates the scale-up and scale-down logic to account for these penalties, and includes comprehensive unit tests. There are no review comments, so I have no feedback to provide.

@rahul2393 rahul2393 added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Sep 1, 2026
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants