11import { isAxiosError } from "axios"
22import { Api } from "coder/site/src/api/api"
33import { Workspace } from "coder/site/src/api/typesGenerated"
4- import EventSource from "eventsource"
54import find from "find-process"
65import * as fs from "fs/promises"
76import * as jsonc from "jsonc-parser"
@@ -20,7 +19,7 @@ import { SSHConfig, SSHValues, mergeSSHConfigValues } from "./sshConfig"
2019import { computeSSHProperties , sshSupportsSetEnv } from "./sshSupport"
2120import { Storage } from "./storage"
2221import { AuthorityPrefix , expandPath , parseRemoteAuthority } from "./util"
23- import { WorkspaceAction } from "./workspaceAction "
22+ import { WorkspaceMonitor } from "./workspaceMonitor "
2423
2524export interface RemoteDetails extends vscode . Disposable {
2625 url : string
@@ -292,9 +291,6 @@ export class Remote {
292291 // Register before connection so the label still displays!
293292 disposables . push ( this . registerLabelFormatter ( remoteAuthority , workspace . owner_name , workspace . name ) )
294293
295- // Initialize any WorkspaceAction notifications (auto-off, upcoming deletion)
296- const action = await WorkspaceAction . init ( this . vscodeProposed , workspaceRestClient , this . storage )
297-
298294 // If the workspace is not in a running state, try to get it running.
299295 const updatedWorkspace = await this . maybeWaitForRunning ( workspaceRestClient , workspace )
300296 if ( ! updatedWorkspace ) {
@@ -376,88 +372,8 @@ export class Remote {
376372 }
377373 }
378374
379- // Watch for workspace updates.
380- this . storage . writeToCoderOutputChannel ( `Establishing watcher for ${ workspaceName } ...` )
381- const workspaceUpdate = new vscode . EventEmitter < Workspace > ( )
382- const watchURL = new URL ( `${ baseUrlRaw } /api/v2/workspaces/${ workspace . id } /watch` )
383- const eventSource = new EventSource ( watchURL . toString ( ) , {
384- headers : {
385- "Coder-Session-Token" : token ,
386- } ,
387- } )
388-
389- const workspaceUpdatedStatus = vscode . window . createStatusBarItem ( vscode . StatusBarAlignment . Left , 999 )
390- disposables . push ( workspaceUpdatedStatus )
391-
392- let hasShownOutdatedNotification = false
393- const refreshWorkspaceUpdatedStatus = ( newWorkspace : Workspace ) => {
394- // If the newly gotten workspace was updated, then we show a notification
395- // to the user that they should update. Only show this once per session.
396- if ( newWorkspace . outdated && ! hasShownOutdatedNotification ) {
397- hasShownOutdatedNotification = true
398- workspaceRestClient
399- . getTemplate ( newWorkspace . template_id )
400- . then ( ( template ) => {
401- return workspaceRestClient . getTemplateVersion ( template . active_version_id )
402- } )
403- . then ( ( version ) => {
404- let infoMessage = `A new version of your workspace is available.`
405- if ( version . message ) {
406- infoMessage = `A new version of your workspace is available: ${ version . message } `
407- }
408- vscode . window . showInformationMessage ( infoMessage , "Update" ) . then ( ( action ) => {
409- if ( action === "Update" ) {
410- vscode . commands . executeCommand ( "coder.workspace.update" , newWorkspace , workspaceRestClient )
411- }
412- } )
413- } )
414- }
415- if ( ! newWorkspace . outdated ) {
416- vscode . commands . executeCommand ( "setContext" , "coder.workspace.updatable" , false )
417- workspaceUpdatedStatus . hide ( )
418- return
419- }
420- workspaceUpdatedStatus . name = "Coder Workspace Update"
421- workspaceUpdatedStatus . text = "$(fold-up) Update Workspace"
422- workspaceUpdatedStatus . command = "coder.workspace.update"
423- // Important for hiding the "Update Workspace" command.
424- vscode . commands . executeCommand ( "setContext" , "coder.workspace.updatable" , true )
425- workspaceUpdatedStatus . show ( )
426- }
427- // Show an initial status!
428- refreshWorkspaceUpdatedStatus ( workspace )
429-
430- eventSource . addEventListener ( "data" , ( event : MessageEvent < string > ) => {
431- const workspace = JSON . parse ( event . data ) as Workspace
432- if ( ! workspace ) {
433- return
434- }
435- refreshWorkspaceUpdatedStatus ( workspace )
436- this . commands . workspace = workspace
437- workspaceUpdate . fire ( workspace )
438- if ( workspace . latest_build . status === "stopping" || workspace . latest_build . status === "stopped" ) {
439- const action = this . vscodeProposed . window . showInformationMessage (
440- "Your workspace stopped!" ,
441- {
442- useCustom : true ,
443- modal : true ,
444- detail : "Reloading the window will start it again." ,
445- } ,
446- "Reload Window" ,
447- )
448- if ( ! action ) {
449- return
450- }
451- this . reloadWindow ( )
452- }
453- // If a new build is initialized for a workspace, we automatically
454- // reload the window. Then the build log will appear, and startup
455- // will continue as expected.
456- if ( workspace . latest_build . status === "starting" ) {
457- this . reloadWindow ( )
458- return
459- }
460- } )
375+ // Watch the workspace for changes.
376+ const monitor = new WorkspaceMonitor ( workspace , workspaceRestClient , this . storage )
461377
462378 // Wait for the agent to connect.
463379 if ( agent . status === "connecting" ) {
@@ -469,7 +385,7 @@ export class Remote {
469385 } ,
470386 async ( ) => {
471387 await new Promise < void > ( ( resolve ) => {
472- const updateEvent = workspaceUpdate . event ( ( workspace ) => {
388+ const updateEvent = monitor . onChange . event ( ( workspace ) => {
473389 if ( ! agent ) {
474390 return
475391 }
@@ -552,8 +468,6 @@ export class Remote {
552468 url : baseUrlRaw ,
553469 token,
554470 dispose : ( ) => {
555- eventSource . close ( )
556- action . cleanupWorkspaceActions ( )
557471 disposables . forEach ( ( d ) => d . dispose ( ) )
558472 } ,
559473 }
@@ -735,7 +649,7 @@ export class Remote {
735649 } else {
736650 statusText += network . preferred_derp + " "
737651 networkStatus . tooltip =
738- "You're connected through a relay 🕵️ .\nWe'll switch over to peer-to-peer when available."
652+ "You're connected through a relay 🕵.\nWe'll switch over to peer-to-peer when available."
739653 }
740654 networkStatus . tooltip +=
741655 "\n\nDownload ↓ " +
@@ -751,9 +665,7 @@ export class Remote {
751665 if ( ! network . p2p ) {
752666 const derpLatency = network . derp_latency [ network . preferred_derp ]
753667
754- networkStatus . tooltip += `You ↔ ${ derpLatency . toFixed ( 2 ) } ms ↔ ${ network . preferred_derp } ↔ ${ (
755- network . latency - derpLatency
756- ) . toFixed ( 2 ) } ms ↔ Workspace`
668+ networkStatus . tooltip += `You ↔ ${ derpLatency . toFixed ( 2 ) } ms ↔ ${ network . preferred_derp } ↔ ${ ( network . latency - derpLatency ) . toFixed ( 2 ) } ms ↔ Workspace`
757669
758670 let first = true
759671 Object . keys ( network . derp_latency ) . forEach ( ( region ) => {
0 commit comments