Skip to content

fix: cancel button hangs during workspace IDE connection (crw-11729)#338

Merged
adietish merged 3 commits into
redhat-developer:mainfrom
vrubezhny:fix/cancel-stuck-on-get-status
Jul 14, 2026
Merged

fix: cancel button hangs during workspace IDE connection (crw-11729)#338
adietish merged 3 commits into
redhat-developer:mainfrom
vrubezhny:fix/cancel-stuck-on-get-status

Conversation

@vrubezhny

Copy link
Copy Markdown
Collaborator

Pass checkCancelled through getStatus/exec, add cancellation monitor that closes streams to unblock reads, use indicator modality state for dialogs, guard exec with pod-running check, and shut down isolated OkHttp clients on cleanup.

Issue: https://redhat.atlassian.net/browse/CRW-11796

Assisted-By: Claude Opus 4.6 noreply@anthropic.com

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@adietish, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: f8d699c6-8513-415b-97e7-ca5718cc4478

📥 Commits

Reviewing files that changed from the base of the PR and between ba99a1a and 80561d2.

📒 Files selected for processing (8)
  • src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnection.kt
  • src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnectionProvider.kt
  • src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt
  • src/main/kotlin/com/redhat/devtools/gateway/server/RemoteIDEServer.kt
  • src/main/kotlin/com/redhat/devtools/gateway/view/ui/Dialogs.kt
  • src/test/kotlin/com/redhat/devtools/gateway/devworkspace/DevWorkspaceRestartTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePodsTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/server/RemoteIDEServerTest.kt
📝 Walkthrough

Walkthrough

Workspace connection startup now propagates modality state to dialogs, checks pod readiness before remote IDE status commands, honors cancellation during polling and exec sessions, and performs stream and client cleanup during cancellation.

Changes

Workspace readiness and cancellation

Layer / File(s) Summary
Connection modality propagation
src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnection.kt, src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnectionProvider.kt, src/main/kotlin/com/redhat/devtools/gateway/view/ui/Dialogs.kt, src/test/kotlin/com/redhat/devtools/gateway/devworkspace/DevWorkspaceRestartTest.kt
Connection and dialog APIs accept modality state, the provider passes the progress indicator state, the workspace startup message is updated, and restart mocks and verifications match the expanded connection signature.
Pod execution cancellation and cleanup
src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt
Pod-running detection, periodic cancellation checks, stream IOException handling, coroutine cancellation, and exec client shutdown are added.
Readiness polling cancellation and pod guard
src/main/kotlin/com/redhat/devtools/gateway/server/RemoteIDEServer.kt, src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnection.kt
Status polling checks cancellation, skips remote status commands when the pod is not running, and passes cancellation and modality state through the connection flow.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DevSpacesConnectionProvider
  participant DevSpacesConnection
  participant RemoteIDEServer
  participant DevWorkspacePods
  participant Dialogs
  DevSpacesConnectionProvider->>DevSpacesConnection: connect(modalityState, checkCancelled)
  DevSpacesConnection->>RemoteIDEServer: getStatus(checkCancelled)
  RemoteIDEServer->>DevWorkspacePods: isPodRunning(pod)
  DevWorkspacePods-->>RemoteIDEServer: pod running state
  RemoteIDEServer-->>DevSpacesConnection: remote IDE status or empty status
  DevSpacesConnection->>Dialogs: ideNotResponding(modalityState)
Loading

Suggested reviewers: azatsarynnyy, adietish, msivasubramaniaan

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main fix: a cancellation hang during workspace IDE connection.
Description check ✅ Passed The description matches the implemented changes around cancellation, dialog modality, pod status checks, and cleanup.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt (1)

124-148: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Close the isolated exec client on early failures onError can fire before onOpen installs the finally cleanup, so the isolated client stays open on exec setup failures. Add shutdownExecClient(execClientApi) there, and keep the outer catch as a fallback for failures that prevent containerAwareExec(...) from returning an ExecHandle.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt`
around lines 124 - 148, Update the onError callback in the containerAwareExec
setup to call shutdownExecClient(execClientApi) after completing the
continuation and before resuming with the exception. Preserve the outer catch in
the surrounding exec flow as a fallback for failures that occur before an
ExecHandle is returned.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt`:
- Around line 124-148: Update the onError callback in the containerAwareExec
setup to call shutdownExecClient(execClientApi) after completing the
continuation and before resuming with the exception. Preserve the outer catch in
the surrounding exec flow as a fallback for failures that occur before an
ExecHandle is returned.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: b465dbcb-ed91-42e6-b872-dddad6a8cd9b

📥 Commits

Reviewing files that changed from the base of the PR and between 98a3c1d and 8434b20.

📒 Files selected for processing (5)
  • src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnection.kt
  • src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnectionProvider.kt
  • src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt
  • src/main/kotlin/com/redhat/devtools/gateway/server/RemoteIDEServer.kt
  • src/main/kotlin/com/redhat/devtools/gateway/view/ui/Dialogs.kt

@vrubezhny
vrubezhny force-pushed the fix/cancel-stuck-on-get-status branch from 8434b20 to ba99a1a Compare July 13, 2026 23:22
@codecov-commenter

codecov-commenter commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 35.84906% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 24.55%. Comparing base (71098f6) to head (80561d2).
⚠️ Report is 387 commits behind head on main.

Files with missing lines Patch % Lines
...hat/devtools/gateway/openshift/DevWorkspacePods.kt 47.05% 11 Missing and 7 partials ⚠️
...lin/com/redhat/devtools/gateway/view/ui/Dialogs.kt 0.00% 11 Missing ⚠️
...com/redhat/devtools/gateway/DevSpacesConnection.kt 25.00% 3 Missing ⚠️
...at/devtools/gateway/DevSpacesConnectionProvider.kt 0.00% 1 Missing ⚠️
.../redhat/devtools/gateway/server/RemoteIDEServer.kt 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            main     #338       +/-   ##
==========================================
+ Coverage   0.00%   24.55%   +24.55%     
==========================================
  Files          4      104      +100     
  Lines         26     4414     +4388     
  Branches       0      846      +846     
==========================================
+ Hits           0     1084     +1084     
- Misses        26     3156     +3130     
- Partials       0      174      +174     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vrubezhny

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt`:
- Around line 107-122: Update the completion coroutine and the exec error
callback to guard both continuation resumes against duplicate completion. In the
shown scope.launch flow, check cont.isActive before resuming stdout, and apply
the same guard to the onError resume path (or use tryResume consistently), while
preserving cancellation and exception propagation behavior.
- Around line 41-50: Update isPodRunning to ensure the readNamespacedPod(name,
namespace).execute() readiness lookup is bounded by an explicit timeout or
observes coroutine cancellation. Preserve the existing false result for missing
metadata and lookup failures, while preventing a hung API call from blocking
startup indefinitely.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 5e263fb3-f842-4746-8c43-6e0b04f01b12

📥 Commits

Reviewing files that changed from the base of the PR and between 8434b20 and ba99a1a.

📒 Files selected for processing (6)
  • src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnection.kt
  • src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnectionProvider.kt
  • src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt
  • src/main/kotlin/com/redhat/devtools/gateway/server/RemoteIDEServer.kt
  • src/main/kotlin/com/redhat/devtools/gateway/view/ui/Dialogs.kt
  • src/test/kotlin/com/redhat/devtools/gateway/devworkspace/DevWorkspaceRestartTest.kt
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnectionProvider.kt
  • src/main/kotlin/com/redhat/devtools/gateway/view/ui/Dialogs.kt
  • src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnection.kt
  • src/main/kotlin/com/redhat/devtools/gateway/server/RemoteIDEServer.kt

Comment thread src/main/kotlin/com/redhat/devtools/gateway/openshift/DevWorkspacePods.kt Outdated
Pass checkCancelled through getStatus/exec, add cancellation monitor
that closes streams to unblock reads, use indicator modality state for
dialogs, guard exec with pod-running check, and shut down isolated
OkHttp clients on cleanup.

Issue: https://redhat.atlassian.net/browse/CRW-11796

Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
Assisted-By: Claude Opus 4.6 <noreply@anthropic.com>
@vrubezhny
vrubezhny force-pushed the fix/cancel-stuck-on-get-status branch from ba99a1a to ce0c03e Compare July 14, 2026 00:11
scope.launch {
try {
listOfNotNull(stdoutJob, stderrJob).joinAll()
checkCancelled?.invoke()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

is this check and others still needed if we check it in a background job already (see lines 94-106)?

@vrubezhny vrubezhny Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Why not? That join might take up to several minutes (usually some 10-20 seconds), so user may decide to cancel at any time during this waiting - and we'll follow with the cancellation immediately after, rather then finishing the operation (its result even if achieved is not needed anymore)

Line 111 (checkCancelled before closed.await()): This is the important one. After streams are closed and reader jobs finish, this catches cancellation before blocking on closed.await() — which could wait indefinitely if onClosed/onError never fires (e.g. the WebSocket setup stalled).

adietish added 2 commits July 14, 2026 12:12
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
@adietish

Copy link
Copy Markdown
Collaborator

I extracted methods in DevWorkspacePods for better readability and added tests. Will verify that I dont get stuck after noon.

@adietish adietish left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM
Could replicate the issue. Your PR fixes it. Kudos, thanks!

@adietish
adietish merged commit c411932 into redhat-developer:main Jul 14, 2026
7 checks passed
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