@@ -10,14 +10,20 @@ import com.coder.toolbox.sdk.v2.models.Workspace
10
10
import com.coder.toolbox.sdk.v2.models.WorkspaceAgent
11
11
import com.coder.toolbox.sdk.v2.models.WorkspaceStatus
12
12
import com.coder.toolbox.settings.CoderSettings
13
+ import kotlinx.coroutines.TimeoutCancellationException
14
+ import kotlinx.coroutines.delay
13
15
import kotlinx.coroutines.flow.StateFlow
14
16
import kotlinx.coroutines.flow.filter
15
17
import kotlinx.coroutines.launch
18
+ import kotlinx.coroutines.time.withTimeout
16
19
import kotlinx.coroutines.yield
17
20
import okhttp3.OkHttpClient
18
21
import java.net.HttpURLConnection
19
22
import java.net.URI
20
23
import java.net.URL
24
+ import kotlin.time.Duration.Companion.minutes
25
+ import kotlin.time.Duration.Companion.seconds
26
+ import kotlin.time.toJavaDuration
21
27
22
28
open class CoderProtocolHandler (
23
29
private val context : CoderToolboxContext ,
@@ -81,29 +87,27 @@ open class CoderProtocolHandler(
81
87
82
88
when (workspace.latestBuild.status) {
83
89
WorkspaceStatus .PENDING , WorkspaceStatus .STARTING ->
84
- // TODO: Wait for the workspace to turn on.
85
- throw IllegalArgumentException (
86
- " The workspace \" $workspaceName \" is ${
87
- workspace.latestBuild.status.toString().lowercase()
88
- } ; please wait then try again" ,
89
- )
90
+ if (restClient.waitForReady(workspace) != true ) {
91
+ context.logger.error(" $workspaceName from $deploymentURL could not be ready on time" )
92
+ context.ui.showErrorInfoPopup(MissingArgumentException (" Can't handle URI because workspace $workspaceName could not be ready on time" ))
93
+ return
94
+ }
90
95
91
96
WorkspaceStatus .STOPPING , WorkspaceStatus .STOPPED ,
92
- WorkspaceStatus .CANCELING , WorkspaceStatus .CANCELED ,
93
- ->
94
- // TODO: Turn on the workspace.
95
- throw IllegalArgumentException (
96
- " The workspace \" $workspaceName \" is ${
97
- workspace.latestBuild.status.toString().lowercase()
98
- } ; please start the workspace and try again " ,
99
- )
97
+ WorkspaceStatus .CANCELING , WorkspaceStatus .CANCELED -> {
98
+ restClient.startWorkspace(workspace)
99
+ if (restClient.waitForReady(workspace) != true ) {
100
+ context.logger.error( " $workspaceName from $deploymentURL could not be started on time " )
101
+ context.ui.showErrorInfoPopup( MissingArgumentException ( " Can't handle URI because workspace $workspaceName could not be started on time " ))
102
+ return
103
+ }
104
+ }
100
105
101
- WorkspaceStatus .FAILED , WorkspaceStatus .DELETING , WorkspaceStatus .DELETED ->
102
- throw IllegalArgumentException (
103
- " The workspace \" $workspaceName \" is ${
104
- workspace.latestBuild.status.toString().lowercase()
105
- } ; unable to connect" ,
106
- )
106
+ WorkspaceStatus .FAILED , WorkspaceStatus .DELETING , WorkspaceStatus .DELETED -> {
107
+ context.logger.error(" Unable to connect to $workspaceName from $deploymentURL " )
108
+ context.ui.showErrorInfoPopup(MissingArgumentException (" Can't handle URI because because we're unable to connect to workspace $workspaceName " ))
109
+ return
110
+ }
107
111
108
112
WorkspaceStatus .RUNNING -> Unit // All is well
109
113
}
@@ -157,6 +161,21 @@ open class CoderProtocolHandler(
157
161
}
158
162
}
159
163
164
+ private suspend fun CoderRestClient.waitForReady (workspace : Workspace ): Boolean {
165
+ var status = workspace.latestBuild.status
166
+ try {
167
+ withTimeout(2 .minutes.toJavaDuration()) {
168
+ while (status != WorkspaceStatus .RUNNING ) {
169
+ delay(1 .seconds)
170
+ status = this @waitForReady.workspace(workspace.id).latestBuild.status
171
+ }
172
+ }
173
+ return true
174
+ } catch (_: TimeoutCancellationException ) {
175
+ return false
176
+ }
177
+ }
178
+
160
179
private suspend fun askUrl (): String? {
161
180
context.ui.showWindow()
162
181
context.envPageManager.showPluginEnvironmentsPage(false )
0 commit comments