@@ -78,8 +78,9 @@ type WorkspaceInfo struct {
78
78
// (parsed from URL)
79
79
IDEPublicPort string
80
80
81
- Ports []PortInfo
82
- Auth * wsapi.WorkspaceAuthentication
81
+ Ports []PortInfo
82
+ Auth * wsapi.WorkspaceAuthentication
83
+ StartedAt time.Time
83
84
}
84
85
85
86
// PortInfo contains all information ws-proxy needs to know about a workspace port
@@ -265,7 +266,7 @@ func (p *RemoteWorkspaceInfoProvider) listen(client wsapi.WorkspaceManagerClient
265
266
}
266
267
267
268
if status .Phase == wsapi .WorkspacePhase_STOPPED {
268
- p .cache .Delete (status .Metadata .MetaId )
269
+ p .cache .Delete (status .Metadata .MetaId , status . Metadata . StartedAt . AsTime () )
269
270
} else {
270
271
info := mapWorkspaceStatusToInfo (status )
271
272
p .cache .Insert (info )
@@ -309,6 +310,7 @@ func mapWorkspaceStatusToInfo(status *wsapi.WorkspaceStatus) *WorkspaceInfo {
309
310
IDEPublicPort : getPortStr (status .Spec .Url ),
310
311
Ports : portInfos ,
311
312
Auth : status .Auth ,
313
+ StartedAt : status .Metadata .StartedAt .AsTime (),
312
314
}
313
315
}
314
316
@@ -400,6 +402,18 @@ func (c *workspaceInfoCache) Insert(info *WorkspaceInfo) {
400
402
}
401
403
402
404
func (c * workspaceInfoCache ) doInsert (info * WorkspaceInfo ) {
405
+ existing := c .infos [info .WorkspaceID ]
406
+ if existing != nil {
407
+ // Do not insert if the current workspace is newer
408
+ // This works around issues when a workspace is deleted then restarted in quick succession
409
+ // and the stopping event occurs after the replocement pod is started
410
+ if ! existing .StartedAt .IsZero () && ! info .StartedAt .IsZero () {
411
+ if existing .StartedAt .After (info .StartedAt ) {
412
+ log .WithField ("workspaceID" , existing .WorkspaceID ).Debug ("ignoring insert of older workspace" )
413
+ return
414
+ }
415
+ }
416
+ }
403
417
c .infos [info .WorkspaceID ] = info
404
418
c .coordsByPublicPort [info .IDEPublicPort ] = & WorkspaceCoords {
405
419
ID : info .WorkspaceID ,
@@ -413,14 +427,23 @@ func (c *workspaceInfoCache) doInsert(info *WorkspaceInfo) {
413
427
}
414
428
}
415
429
416
- func (c * workspaceInfoCache ) Delete (workspaceID string ) {
430
+ func (c * workspaceInfoCache ) Delete (workspaceID string , startedAt time. Time ) {
417
431
c .cond .L .Lock ()
418
432
defer c .cond .L .Unlock ()
419
433
420
434
info , present := c .infos [workspaceID ]
421
435
if ! present || info == nil {
422
436
return
423
437
}
438
+ // Do not delete if the current workspace info is newer
439
+ // This works around issues when a workspace is deleted then restarted in quick succession
440
+ // and the delete event occurs after the replocement pod is started
441
+ if ! startedAt .IsZero () && ! info .StartedAt .IsZero () {
442
+ if info .StartedAt .After (startedAt ) {
443
+ log .WithField ("workspaceID" , workspaceID ).WithField ("startedAt" , startedAt ).WithField ("info" , info ).Debug ("ignoring delete of older workspace" )
444
+ return
445
+ }
446
+ }
424
447
delete (c .coordsByPublicPort , info .IDEPublicPort )
425
448
delete (c .infos , workspaceID )
426
449
}
0 commit comments