@@ -26,6 +26,7 @@ import com.jetbrains.toolbox.api.remoteDev.RemoteProvider
2626import com.jetbrains.toolbox.api.ui.actions.ActionDelimiter
2727import com.jetbrains.toolbox.api.ui.actions.ActionDescription
2828import com.jetbrains.toolbox.api.ui.components.UiPage
29+ import kotlinx.coroutines.CoroutineName
2930import kotlinx.coroutines.ExperimentalCoroutinesApi
3031import kotlinx.coroutines.Job
3132import kotlinx.coroutines.channels.Channel
@@ -87,113 +88,114 @@ class CoderRemoteProvider(
8788 * workspace is added, reconfigure SSH using the provided cli (including the
8889 * first time).
8990 */
90- private fun poll (client : CoderRestClient , cli : CoderCLIManager ): Job = context.cs.launch {
91- var lastPollTime = TimeSource .Monotonic .markNow()
92- while (isActive) {
93- try {
94- context.logger.debug(" Fetching workspace agents from ${client.url} " )
95- val resolvedEnvironments = client.workspaces().flatMap { ws ->
96- // Agents are not included in workspaces that are off
97- // so fetch them separately.
98- when (ws.latestBuild.status) {
99- WorkspaceStatus .RUNNING -> ws.latestBuild.resources
100- else -> emptyList()
101- }.ifEmpty {
102- client.resources(ws)
103- }.flatMap { resource ->
104- resource.agents?.distinctBy {
105- // There can be duplicates with coder_agent_instance.
106- // TODO: Can we just choose one or do they hold
107- // different information?
108- it.name
109- }?.map { agent ->
110- // If we have an environment already, update that.
111- val env = CoderRemoteEnvironment (context, client, cli, ws, agent)
112- lastEnvironments.firstOrNull { it == env }?.let {
113- it.update(ws, agent)
114- it
115- } ? : env
116- } ? : emptyList()
117- }
118- }.toSet()
91+ private fun poll (client : CoderRestClient , cli : CoderCLIManager ): Job =
92+ context.cs.launch(CoroutineName (" Workspace Poller" )) {
93+ var lastPollTime = TimeSource .Monotonic .markNow()
94+ while (isActive) {
95+ try {
96+ context.logger.debug(" Fetching workspace agents from ${client.url} " )
97+ val resolvedEnvironments = client.workspaces().flatMap { ws ->
98+ // Agents are not included in workspaces that are off
99+ // so fetch them separately.
100+ when (ws.latestBuild.status) {
101+ WorkspaceStatus .RUNNING -> ws.latestBuild.resources
102+ else -> emptyList()
103+ }.ifEmpty {
104+ client.resources(ws)
105+ }.flatMap { resource ->
106+ resource.agents?.distinctBy {
107+ // There can be duplicates with coder_agent_instance.
108+ // TODO: Can we just choose one or do they hold
109+ // different information?
110+ it.name
111+ }?.map { agent ->
112+ // If we have an environment already, update that.
113+ val env = CoderRemoteEnvironment (context, client, cli, ws, agent)
114+ lastEnvironments.firstOrNull { it == env }?.let {
115+ it.update(ws, agent)
116+ it
117+ } ? : env
118+ } ? : emptyList()
119+ }
120+ }.toSet()
119121
120- // In case we logged out while running the query.
121- if (! isActive) {
122- return @launch
123- }
122+ // In case we logged out while running the query.
123+ if (! isActive) {
124+ return @launch
125+ }
124126
125- // Reconfigure if environments changed.
126- if (lastEnvironments.size != resolvedEnvironments.size || lastEnvironments != resolvedEnvironments) {
127- context.logger.info(" Workspaces have changed, reconfiguring CLI: $resolvedEnvironments " )
128- cli.configSsh(resolvedEnvironments.map { it.asPairOfWorkspaceAndAgent() }.toSet())
129- }
127+ // Reconfigure if environments changed.
128+ if (lastEnvironments.size != resolvedEnvironments.size || lastEnvironments != resolvedEnvironments) {
129+ context.logger.info(" Workspaces have changed, reconfiguring CLI: $resolvedEnvironments " )
130+ cli.configSsh(resolvedEnvironments.map { it.asPairOfWorkspaceAndAgent() }.toSet())
131+ }
130132
131- environments.update {
132- LoadableState .Value (resolvedEnvironments.toList())
133- }
134- if (! isInitialized.value) {
135- context.logger.info(" Environments for ${client.url} are now initialized" )
136- isInitialized.update {
137- true
133+ environments.update {
134+ LoadableState .Value (resolvedEnvironments.toList())
135+ }
136+ if (! isInitialized.value) {
137+ context.logger.info(" Environments for ${client.url} are now initialized" )
138+ isInitialized.update {
139+ true
140+ }
141+ }
142+ lastEnvironments.apply {
143+ clear()
144+ addAll(resolvedEnvironments.sortedBy { it.id })
138145 }
139- }
140- lastEnvironments.apply {
141- clear()
142- addAll(resolvedEnvironments.sortedBy { it.id })
143- }
144146
145- if (WorkspaceConnectionManager .shouldEstablishWorkspaceConnections) {
146- WorkspaceConnectionManager .allConnected().forEach { wsId ->
147- val env = lastEnvironments.firstOrNull() { it.id == wsId }
148- if (env != null && ! env.isConnected()) {
149- context.logger.info(" Establishing lost SSH connection for workspace with id $wsId " )
150- if (! env.startSshConnection()) {
151- context.logger.info(" Can't establish lost SSH connection for workspace with id $wsId " )
147+ if (WorkspaceConnectionManager .shouldEstablishWorkspaceConnections) {
148+ WorkspaceConnectionManager .allConnected().forEach { wsId ->
149+ val env = lastEnvironments.firstOrNull() { it.id == wsId }
150+ if (env != null && ! env.isConnected()) {
151+ context.logger.info(" Establishing lost SSH connection for workspace with id $wsId " )
152+ if (! env.startSshConnection()) {
153+ context.logger.info(" Can't establish lost SSH connection for workspace with id $wsId " )
154+ }
152155 }
153156 }
157+ WorkspaceConnectionManager .reset()
154158 }
155- WorkspaceConnectionManager .reset()
156- }
157159
158- WorkspaceConnectionManager .collectStatuses(lastEnvironments)
159- } catch (_: CancellationException ) {
160- context.logger.debug(" ${client.url} polling loop canceled" )
161- break
162- } catch (ex: Exception ) {
163- val elapsed = lastPollTime.elapsedNow()
164- if (elapsed > POLL_INTERVAL * 2 ) {
165- context.logger.info(" wake-up from an OS sleep was detected" )
166- } else {
167- context.logger.error(ex, " workspace polling error encountered" )
168- if (ex is APIResponseException && ex.isTokenExpired) {
169- WorkspaceConnectionManager .shouldEstablishWorkspaceConnections = true
170- close()
171- context.envPageManager.showPluginEnvironmentsPage()
172- errorBuffer.add(ex)
173- break
160+ WorkspaceConnectionManager .collectStatuses(lastEnvironments)
161+ } catch (_: CancellationException ) {
162+ context.logger.debug(" ${client.url} polling loop canceled" )
163+ break
164+ } catch (ex: Exception ) {
165+ val elapsed = lastPollTime.elapsedNow()
166+ if (elapsed > POLL_INTERVAL * 2 ) {
167+ context.logger.info(" wake-up from an OS sleep was detected" )
168+ } else {
169+ context.logger.error(ex, " workspace polling error encountered" )
170+ if (ex is APIResponseException && ex.isTokenExpired) {
171+ WorkspaceConnectionManager .shouldEstablishWorkspaceConnections = true
172+ close()
173+ context.envPageManager.showPluginEnvironmentsPage()
174+ errorBuffer.add(ex)
175+ break
176+ }
174177 }
175178 }
176- }
177179
178- select {
179- onTimeout(POLL_INTERVAL ) {
180- context.logger.debug(" workspace poller waked up by the $POLL_INTERVAL timeout" )
181- }
182- triggerSshConfig.onReceive { shouldTrigger ->
183- if (shouldTrigger) {
184- context.logger.debug(" workspace poller waked up because it should reconfigure the ssh configurations" )
185- cli.configSsh(lastEnvironments.map { it.asPairOfWorkspaceAndAgent() }.toSet())
180+ select {
181+ onTimeout(POLL_INTERVAL ) {
182+ context.logger.debug(" workspace poller waked up by the $POLL_INTERVAL timeout" )
186183 }
187- }
188- triggerProviderVisible.onReceive { isCoderProviderVisible ->
189- if (isCoderProviderVisible) {
190- context.logger.debug(" workspace poller waked up by Coder Toolbox which is currently visible, fetching latest workspace statuses" )
184+ triggerSshConfig.onReceive { shouldTrigger ->
185+ if (shouldTrigger) {
186+ context.logger.debug(" workspace poller waked up because it should reconfigure the ssh configurations" )
187+ cli.configSsh(lastEnvironments.map { it.asPairOfWorkspaceAndAgent() }.toSet())
188+ }
189+ }
190+ triggerProviderVisible.onReceive { isCoderProviderVisible ->
191+ if (isCoderProviderVisible) {
192+ context.logger.debug(" workspace poller waked up by Coder Toolbox which is currently visible, fetching latest workspace statuses" )
193+ }
191194 }
192195 }
196+ lastPollTime = TimeSource .Monotonic .markNow()
193197 }
194- lastPollTime = TimeSource .Monotonic .markNow()
195198 }
196- }
197199
198200 /* *
199201 * Stop polling, clear the client and environments, then go back to the
@@ -221,7 +223,7 @@ class CoderRemoteProvider(
221223 override val additionalPluginActions: StateFlow <List <ActionDescription >> = MutableStateFlow (
222224 listOf (
223225 Action (context.i18n.ptrl(" Create workspace" )) {
224- context.cs.launch {
226+ context.cs.launch( CoroutineName ( " Create Workspace Action " )) {
225227 context.desktop.browse(client?.url?.withPath(" /templates" ).toString()) {
226228 context.ui.showErrorInfoPopup(it)
227229 }
@@ -299,7 +301,7 @@ class CoderRemoteProvider(
299301 visibility
300302 }
301303 if (visibility.providerVisible) {
302- context.cs.launch {
304+ context.cs.launch( CoroutineName ( " Notify Plugin Visibility " )) {
303305 triggerProviderVisible.send(true )
304306 }
305307 }
@@ -396,11 +398,17 @@ class CoderRemoteProvider(
396398 context.secrets.lastDeploymentURL = client.url.toString()
397399 context.secrets.lastToken = client.token ? : " "
398400 context.secrets.storeTokenFor(client.url, context.secrets.lastToken)
401+ context.logger.info(" Deployment URL and token were stored and will be available for automatic connection" )
399402 this .client = client
400- pollJob?.cancel()
403+ pollJob?.let {
404+ it.cancel()
405+ context.logger.info(" Workspace poll job with reference ${pollJob} was canceled" )
406+ }
401407 environments.showLoadingMessage()
402408 coderHeaderPage.setTitle(context.i18n.pnotr(client.url.toString()))
409+ context.logger.info(" Displaying ${client.url} in the UI" )
403410 pollJob = poll(client, cli)
411+ context.logger.info(" Workspace poll job created with reference $pollJob " )
404412 context.envPageManager.showPluginEnvironmentsPage()
405413 }
406414
0 commit comments