Conversation
Workspace action progress was previously refreshed only by the five-second polling loop, which made start, stop, update-and-start, and update-and-restart operations appear stale between polls. We added a workspace progress watcher that uses Coder's workspace and build-log WebSockets on supported deployments. The remote environment uses those events only for the progress description, while the workspace poller remains responsible for workspace and agent state. We added version gating and failure handling so older deployments and unavailable WebSocket connections continue through the existing polling path. We also added coverage for streaming output, state isolation, lifecycle cleanup, and fallback behavior.
Workspace action progress was previously refreshed only every five seconds, and the streaming capability and transport responsibilities were spread across the environment, watcher, and REST client. We added workspace progress WebSockets to the CLI feature set and changed the remote environment to choose between streaming and REST polling before invoking either path. The Coder API facade now defines the streaming endpoints, while the REST client owns WebSocket transport and event decoding. We changed the workspace progress watcher to consume ID-based streaming methods and remain focused on build progression. Runtime failures still fall back to polling, and the updated coverage verifies feature selection, streaming behavior, state isolation, and failure handling.
Workspace action progress was previously available only every five seconds, and the first streaming implementation added unnecessary abstractions to an environment class whose mixed ordering made the behavior difficult to follow. We removed the watcher interface, shortened the concrete watcher name, and changed the callback holder into three named function parameters. The remote environment now constructs the watcher directly, while the watcher keeps workspace-first argument ordering and remains focused on streamed build progress. We reorganized CoderRemoteEnvironment in depth-first call order, grouped overridden entry points with their supporting methods, and moved file-level extensions below the class. The polling fallback and workspace and agent state ownership remain unchanged.
fioan89
marked this pull request as ready for review
September 24, 2026 19:49
fioan89
requested review from
code-asher,
jeremyruppel and
matifali
and removed request for
code-asher
September 24, 2026 19:49
| if (log.id <= lastLogID) { | ||
| false | ||
| } else { | ||
| lastLogID = log.id |
There was a problem hiding this comment.
I'm not sure how to better express this in kotlin, but because the lock routine returns a boolean, the lastLogID assignment here feels like a side effect. is there a good/clean way to tease these apart?
Collaborator
Author
There was a problem hiding this comment.
I'm not happy how the progress watcher turned out, I'll try to simplify and improve it.
Workspace action progress was previously available only every five seconds, and the initial streaming path contained repeated action workflows and lifecycle details that were difficult to interpret. We changed CoderRemoteEnvironment to share the workspace build request workflow and replaced the ambiguous retry flag with an explicit watcher restart path. The environment still uses polling for workspace and agent state and falls back to REST progress requests when streaming becomes unavailable. We changed WorkspaceProgressWatcher to use its activity property consistently, isolated duplicate-log tracking, and distinguished expected build-log completion from abnormal socket closure. We also added coverage showing that abnormal closure disables streaming and activates failure handling.
Workspace build progress was provided only every five seconds by polling, leaving actions without timely feedback. We changed CoderRemoteEnvironment to share the action lifecycle and show queued progress immediately, while its polling loop remains responsible for workspace and agent state. We changed WorkspaceProgressWatcher to stream build progress when supported, reconnect failed sockets with backoff, and retrieve logs through REST while streaming is unavailable. We changed CoderRestClient to report socket openings and removed CLI text-progress callbacks so the watcher owns progress descriptions. We added tests for action lifecycle, streaming, fallback, and reconnection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Workspace action progress was previously refreshed only by the five-second polling loop, which made start, stop, update-and-start, and update-and-restart operations appear stale between polls.
We added a workspace progress watcher that uses Coder's workspace and build-log WebSockets on supported deployments. The remote environment uses those events only for the progress description, while the workspace poller remains responsible for workspace and agent state.
We added version gating and failure handling so older deployments and unavailable WebSocket connections continue through the existing polling path. We also added coverage for streaming output, state isolation, lifecycle cleanup, and fallback behavior.