Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit792dba9

Browse files
authored
fix: update&start outdated workspaces (#128)
URI handling was not able to start workspaces that were stopped and alsooutdated. With this PR we check the ws status and call the proper RESTendpoint depending on whether the workspace is outdated or not.During URI handling we can wait for workspaces to start up. The existingimplementation had no visual feedback that we are waiting/doinganything. With this PR the header bar shows a nice work in progressvisual. Additionally, the deployment URL was not properly refreshed whenswitching between different urls via URI handling. This is also fixed byforcing TBX to render a blank page for a very short period of time andthen going back to the main page.
1 parent77f39cf commit792dba9

File tree

7 files changed

+72
-15
lines changed

7 files changed

+72
-15
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
###Fixed
66

77
-`Stop` action is now available for running workspaces that have an out of date template.
8+
- outdated and stopped workspaces are now updated and started when handling URI
89

910
##0.3.0 - 2025-06-10
1011

‎src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import com.coder.toolbox.util.DialogUi
99
importcom.coder.toolbox.util.withPath
1010
importcom.coder.toolbox.views.Action
1111
importcom.coder.toolbox.views.AuthWizardPage
12-
importcom.coder.toolbox.views.CoderPage
1312
importcom.coder.toolbox.views.CoderSettingsPage
1413
importcom.coder.toolbox.views.NewEnvironmentPage
1514
importcom.coder.toolbox.views.state.AuthWizardState
@@ -110,7 +109,6 @@ class CoderRemoteProvider(
110109
return@launch
111110
}
112111

113-
114112
// Reconfigure if environments changed.
115113
if (lastEnvironments.size!= resolvedEnvironments.size|| lastEnvironments!= resolvedEnvironments) {
116114
context.logger.info("Workspaces have changed, reconfiguring CLI:$resolvedEnvironments")
@@ -269,12 +267,25 @@ class CoderRemoteProvider(
269267
* Handle incoming links (like from the dashboard).
270268
*/
271269
overridesuspendfunhandleUri(uri:URI) {
272-
linkHandler.handle(uri, shouldDoAutoLogin()) { restClient, cli->
270+
linkHandler.handle(
271+
uri, shouldDoAutoLogin(),
272+
{
273+
coderHeaderPage.isBusyCreatingNewEnvironment.update {
274+
true
275+
}
276+
},
277+
{
278+
coderHeaderPage.isBusyCreatingNewEnvironment.update {
279+
false
280+
}
281+
}
282+
) { restClient, cli->
273283
// stop polling and de-initialize resources
274284
close()
275285
// start initialization with the new settings
276286
this@CoderRemoteProvider.client= restClient
277287
coderHeaderPage=NewEnvironmentPage(context, context.i18n.pnotr(restClient.url.toString()))
288+
278289
environments.showLoadingMessage()
279290
pollJob= poll(restClient, cli)
280291
}
@@ -332,7 +343,7 @@ class CoderRemoteProvider(
332343

333344
privatefunshouldDoAutoLogin():Boolean= firstRun&& context.secrets.rememberMe==true
334345

335-
privatefunonConnect(client:CoderRestClient,cli:CoderCLIManager) {
346+
privatesuspendfunonConnect(client:CoderRestClient,cli:CoderCLIManager) {
336347
// Store the URL and token for use next time.
337348
context.secrets.lastDeploymentURL= client.url.toString()
338349
context.secrets.lastToken= client.token?:""
@@ -344,8 +355,7 @@ class CoderRemoteProvider(
344355
environments.showLoadingMessage()
345356
coderHeaderPage=NewEnvironmentPage(context, context.i18n.pnotr(client.url.toString()))
346357
pollJob= poll(client, cli)
347-
context.ui.showUiPage(CoderPage.emptyPage(context))
348-
goToEnvironmentsPage()
358+
context.refreshMainPage()
349359
}
350360

351361
privatefun MutableStateFlow<LoadableState<List<RemoteProviderEnvironment>>>.showLoadingMessage() {

‎src/main/kotlin/com/coder/toolbox/CoderToolboxContext.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.coder.toolbox
33
importcom.coder.toolbox.store.CoderSecretsStore
44
importcom.coder.toolbox.store.CoderSettingsStore
55
importcom.coder.toolbox.util.toURL
6+
importcom.coder.toolbox.views.CoderPage
67
importcom.jetbrains.toolbox.api.core.diagnostics.Logger
78
importcom.jetbrains.toolbox.api.core.os.LocalDesktopManager
89
importcom.jetbrains.toolbox.api.localization.LocalizableStringFactory
@@ -13,8 +14,10 @@ import com.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateColorPalette
1314
importcom.jetbrains.toolbox.api.remoteDev.ui.EnvironmentUiPageManager
1415
importcom.jetbrains.toolbox.api.ui.ToolboxUi
1516
importkotlinx.coroutines.CoroutineScope
17+
importkotlinx.coroutines.delay
1618
importjava.net.URL
1719
importjava.util.UUID
20+
importkotlin.time.Duration.Companion.milliseconds
1821

1922
@Suppress("UnstableApiUsage")
2023
data classCoderToolboxContext(
@@ -88,4 +91,26 @@ data class CoderToolboxContext(
8891
i18n.ptrl("OK")
8992
)
9093
}
94+
95+
/**
96+
* Forces the title bar on the main page to be refreshed
97+
*/
98+
suspendfunrefreshMainPage() {
99+
// the url/title on the main page is only refreshed if
100+
// we're navigating to the main env page from another page.
101+
// If TBX is already on the main page the title is not refreshed
102+
// hence we force a navigation from a blank page.
103+
ui.showUiPage(CoderPage.emptyPage(this))
104+
105+
106+
// Toolbox uses an internal shared flow with a buffer of 4 items and a DROP_OLDEST strategy.
107+
// Both showUiPage and showPluginEnvironmentsPage send events to this flow.
108+
// If we emit two events back-to-back, the first one often gets dropped and only the second is shown.
109+
// To reduce this risk, we add a small delay to let the UI coroutine process the first event.
110+
// Simply yielding the coroutine isn't reliable, especially right after Toolbox starts via URI handling.
111+
// Based on my testing, a 5–10 ms delay is enough to ensure the blank page is processed,
112+
// while still short enough to be invisible to users.
113+
delay(10.milliseconds)
114+
envPageManager.showPluginEnvironmentsPage()
115+
}
91116
}

‎src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ open class CoderProtocolHandler(
4343
suspendfunhandle(
4444
uri:URI,
4545
shouldWaitForAutoLogin:Boolean,
46+
markAsBusy: ()->Unit,
47+
unmarkAsBusy: ()->Unit,
4648
reInitialize:suspend (CoderRestClient,CoderCLIManager)->Unit
4749
) {
4850
val params= uri.toQueryParameters()
@@ -62,16 +64,27 @@ open class CoderProtocolHandler(
6264
val workspaceName= resolveWorkspaceName(params)?:return
6365
val restClient= buildRestClient(deploymentURL, token)?:return
6466
val workspace= restClient.workspaces().matchName(workspaceName, deploymentURL)?:return
65-
if (!prepareWorkspace(workspace, restClient, workspaceName, deploymentURL))return
66-
67-
// we resolve the agent after the workspace is started otherwise we can get misleading
68-
// errors like: no agent available while workspace is starting or stopping
69-
val agent= resolveAgent(params, workspace)?:return
70-
if (!ensureAgentIsReady(workspace, agent))return
7167

7268
val cli= configureCli(deploymentURL, restClient)
7369
reInitialize(restClient, cli)
7470

71+
var agent:WorkspaceAgent
72+
try {
73+
markAsBusy()
74+
context.refreshMainPage()
75+
if (!prepareWorkspace(workspace, restClient, workspaceName, deploymentURL))return
76+
// we resolve the agent after the workspace is started otherwise we can get misleading
77+
// errors like: no agent available while workspace is starting or stopping
78+
// we also need to retrieve the workspace again to have the latest resources (ex: agent)
79+
// attached to the workspace.
80+
agent= resolveAgent(
81+
params,
82+
restClient.workspace(workspace.id)
83+
)?:return
84+
if (!ensureAgentIsReady(workspace, agent))return
85+
}finally {
86+
unmarkAsBusy()
87+
}
7588
val environmentId="${workspace.name}.${agent.name}"
7689
context.showEnvironmentPage(environmentId)
7790

@@ -173,7 +186,11 @@ open class CoderProtocolHandler(
173186
}
174187

175188
try {
176-
restClient.startWorkspace(workspace)
189+
if (workspace.outdated) {
190+
restClient.updateWorkspace(workspace)
191+
}else {
192+
restClient.startWorkspace(workspace)
193+
}
177194
}catch (e:Exception) {
178195
context.logAndShowError(
179196
CAN_T_HANDLE_URI_TITLE,
@@ -428,6 +445,7 @@ open class CoderProtocolHandler(
428445
}
429446
}
430447

448+
431449
privatefun CoderToolboxContext.popupPluginMainPage() {
432450
this.ui.showWindow()
433451
this.envPageManager.showPluginEnvironmentsPage(true)

‎src/main/kotlin/com/coder/toolbox/views/AuthWizardPage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class AuthWizardPage(
1616
privatevalcontext:CoderToolboxContext,
1717
privatevalsettingsPage:CoderSettingsPage,
1818
initialAutoLogin:Boolean =false,
19-
onConnect: (
19+
onConnect:suspend(
2020
client:CoderRestClient,
2121
cli:CoderCLIManager,
2222
)->Unit,

‎src/main/kotlin/com/coder/toolbox/views/CoderPage.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.jetbrains.toolbox.api.core.ui.icons.SvgIcon.IconType
66
importcom.jetbrains.toolbox.api.localization.LocalizableString
77
importcom.jetbrains.toolbox.api.ui.actions.RunnableActionDescription
88
importcom.jetbrains.toolbox.api.ui.components.UiPage
9+
importkotlinx.coroutines.flow.MutableStateFlow
910
importkotlinx.coroutines.launch
1011
importjava.util.UUID
1112

@@ -39,6 +40,8 @@ abstract class CoderPage(
3940
SvgIcon(byteArrayOf(), type=IconType.Masked)
4041
}
4142

43+
overrideval isBusyCreatingNewEnvironment:MutableStateFlow<Boolean>=MutableStateFlow(false)
44+
4245
/**
4346
* Show an error as a popup on this page.
4447
*/

‎src/main/kotlin/com/coder/toolbox/views/ConnectStep.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ConnectStep(
2828
privatevalshouldAutoLogin:StateFlow<Boolean>,
2929
privatevalnotify: (String,Throwable)->Unit,
3030
privatevalrefreshWizard: ()->Unit,
31-
privatevalonConnect: (
31+
privatevalonConnect:suspend(
3232
client:CoderRestClient,
3333
cli:CoderCLIManager,
3434
)->Unit,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp