@@ -69,6 +69,15 @@ func WithClock(clock quartz.Clock) Option {
69
69
}
70
70
}
71
71
72
+ // WithCacheDuration sets the cache duration for the API.
73
+ // This is used to control how often the API refreshes the list of
74
+ // containers. The default is 10 seconds.
75
+ func WithCacheDuration (d time.Duration ) Option {
76
+ return func (api * API ) {
77
+ api .cacheDuration = d
78
+ }
79
+ }
80
+
72
81
// WithExecer sets the agentexec.Execer implementation to use.
73
82
func WithExecer (execer agentexec.Execer ) Option {
74
83
return func (api * API ) {
@@ -336,14 +345,29 @@ func (api *API) getContainers(ctx context.Context) (codersdk.WorkspaceAgentListC
336
345
}
337
346
338
347
// Check if the container is running and update the known devcontainers.
339
- for _ , container := range updated .Containers {
348
+ for i := range updated .Containers {
349
+ container := & updated .Containers [i ]
340
350
workspaceFolder := container .Labels [DevcontainerLocalFolderLabel ]
341
351
configFile := container .Labels [DevcontainerConfigFileLabel ]
342
352
343
353
if workspaceFolder == "" {
344
354
continue
345
355
}
346
356
357
+ container .DevcontainerDirty = dirtyStates [workspaceFolder ]
358
+ if container .DevcontainerDirty {
359
+ lastModified , hasModTime := api .configFileModifiedTimes [configFile ]
360
+ if hasModTime && container .CreatedAt .After (lastModified ) {
361
+ api .logger .Info (ctx , "new container created after config modification, not marking as dirty" ,
362
+ slog .F ("container" , container .ID ),
363
+ slog .F ("created_at" , container .CreatedAt ),
364
+ slog .F ("config_modified_at" , lastModified ),
365
+ slog .F ("file" , configFile ),
366
+ )
367
+ container .DevcontainerDirty = false
368
+ }
369
+ }
370
+
347
371
// Check if this is already in our known list.
348
372
if knownIndex := slices .IndexFunc (api .knownDevcontainers , func (dc codersdk.WorkspaceAgentDevcontainer ) bool {
349
373
return dc .WorkspaceFolder == workspaceFolder
@@ -356,7 +380,7 @@ func (api *API) getContainers(ctx context.Context) (codersdk.WorkspaceAgentListC
356
380
}
357
381
}
358
382
api .knownDevcontainers [knownIndex ].Running = container .Running
359
- api .knownDevcontainers [knownIndex ].Container = & container
383
+ api .knownDevcontainers [knownIndex ].Container = container
360
384
361
385
// Check if this container was created after the config
362
386
// file was modified.
@@ -395,28 +419,14 @@ func (api *API) getContainers(ctx context.Context) (codersdk.WorkspaceAgentListC
395
419
}
396
420
}
397
421
398
- dirty := dirtyStates [workspaceFolder ]
399
- if dirty {
400
- lastModified , hasModTime := api .configFileModifiedTimes [configFile ]
401
- if hasModTime && container .CreatedAt .After (lastModified ) {
402
- api .logger .Info (ctx , "new container created after config modification, not marking as dirty" ,
403
- slog .F ("container" , container .ID ),
404
- slog .F ("created_at" , container .CreatedAt ),
405
- slog .F ("config_modified_at" , lastModified ),
406
- slog .F ("file" , configFile ),
407
- )
408
- dirty = false
409
- }
410
- }
411
-
412
422
api .knownDevcontainers = append (api .knownDevcontainers , codersdk.WorkspaceAgentDevcontainer {
413
423
ID : uuid .New (),
414
424
Name : name ,
415
425
WorkspaceFolder : workspaceFolder ,
416
426
ConfigPath : configFile ,
417
427
Running : container .Running ,
418
- Dirty : dirty ,
419
- Container : & container ,
428
+ Dirty : container . DevcontainerDirty ,
429
+ Container : container ,
420
430
})
421
431
}
422
432
@@ -510,6 +520,13 @@ func (api *API) handleDevcontainerRecreate(w http.ResponseWriter, r *http.Reques
510
520
slog .F ("name" , api .knownDevcontainers [i ].Name ),
511
521
)
512
522
api .knownDevcontainers [i ].Dirty = false
523
+ // TODO(mafredri): This should be handled by a service that
524
+ // updates the devcontainer state periodically and on-demand.
525
+ api .knownDevcontainers [i ].Container = nil
526
+ // Set the modified time to the zero value to indicate that
527
+ // the containers list must be refreshed. This will see to
528
+ // it that the new container is re-assigned.
529
+ api .mtime = time.Time {}
513
530
}
514
531
return
515
532
}
@@ -579,6 +596,9 @@ func (api *API) markDevcontainerDirty(configPath string, modifiedAt time.Time) {
579
596
slog .F ("modified_at" , modifiedAt ),
580
597
)
581
598
api .knownDevcontainers [i ].Dirty = true
599
+ if api .knownDevcontainers [i ].Container != nil {
600
+ api .knownDevcontainers [i ].Container .DevcontainerDirty = true
601
+ }
582
602
}
583
603
}
584
604
})
0 commit comments