Skip to content

Commit cc39604

Browse files
authored
Stabilise colors of running experiments (#2877)
* add rough prototype for keeping colors stable when an experiment is running * fix end to end test * do not select experiments by default (only if newly created) * refactor code * add tests * try to eliminate an edge case * self review
1 parent f3ec528 commit cc39604

File tree

21 files changed

+922
-552
lines changed

21 files changed

+922
-552
lines changed

extension/src/experiments/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,18 @@ export class Experiments extends BaseRepository<TableData> {
410410
return this.experiments.getSelectedRevisions()
411411
}
412412

413+
public setRevisionCollected(revisions: string[]) {
414+
this.experiments.setRevisionCollected(revisions)
415+
}
416+
413417
public getBranchRevisions() {
414418
return this.experiments.getBranchRevisions()
415419
}
416420

421+
public getFinishedExperiments() {
422+
return this.experiments.getFinishedExperiments()
423+
}
424+
417425
public getExperimentDisplayName(experimentId: string) {
418426
const experiment = this.experiments
419427
.getCombinedList()
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
import { Experiment, isRunning } from '../webview/contract'
1+
import { Experiment, isRunning, RunningExperiment } from '../webview/contract'
22

33
export class ExperimentsAccumulator {
44
public workspace = {} as Experiment
55
public branches: Experiment[] = []
66
public checkpointsByTip: Map<string, Experiment[]> = new Map()
77
public experimentsByBranch: Map<string, Experiment[]> = new Map()
8-
public hasRunning: boolean
8+
public runningExperiments: RunningExperiment[]
99

1010
constructor(workspace: Experiment | undefined) {
1111
if (workspace) {
1212
this.workspace = workspace
1313
}
14-
this.hasRunning = isRunning(workspace?.status)
14+
this.runningExperiments = []
15+
if (isRunning(workspace?.status)) {
16+
this.runningExperiments.push({ executor: 'workspace', id: 'workspace' })
17+
}
1518
}
1619
}

extension/src/experiments/model/collect.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,9 @@ const collectHasRunningExperiment = (
237237
acc: ExperimentsAccumulator,
238238
experiment: Experiment
239239
) => {
240-
if (isRunning(experiment.status)) {
241-
acc.hasRunning = true
240+
const { executor, id, status } = experiment
241+
if (isRunning(status) && executor) {
242+
acc.runningExperiments.push({ executor, id })
242243
}
243244
}
244245

extension/src/experiments/model/index.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,11 @@ describe('ExperimentsModel', () => {
208208
baseline: buildTestExperiment(3)
209209
}
210210
})
211+
experimentsModel.toggleStatus(runningExperiment)
211212

212213
expect(experimentsModel.getSelectedExperiments()).toStrictEqual([
213214
expect.objectContaining({
214-
displayColor: expColor,
215+
displayColor: workspaceColor,
215216
id: runningExperiment,
216217
label: 'tip2'
217218
})

extension/src/experiments/model/index.ts

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ import {
1313
ExperimentAugmented,
1414
ExperimentWithType
1515
} from './filterBy/collect'
16-
import { collectColoredStatus, collectSelected } from './status/collect'
16+
import {
17+
collectColoredStatus,
18+
collectFinishedRunningExperiments,
19+
collectSelected,
20+
collectStartedRunningExperiments
21+
} from './status/collect'
1722
import { Color, copyOriginalColors } from './status/colors'
1823
import {
1924
canSelect,
@@ -23,7 +28,12 @@ import {
2328
UNSELECTED
2429
} from './status'
2530
import { collectFlatExperimentParams } from './modify/collect'
26-
import { Experiment, isQueued, Row } from '../webview/contract'
31+
import {
32+
Experiment,
33+
isQueued,
34+
Row,
35+
RunningExperiment
36+
} from '../webview/contract'
2737
import {
2838
definedAndNonEmpty,
2939
reorderListSubset,
@@ -68,7 +78,9 @@ export class ExperimentsModel extends ModelWithPersistence {
6878
private useFiltersForSelection = false
6979

7080
private currentSorts: SortDefinition[]
71-
private hasRunning = false
81+
private running: RunningExperiment[] = []
82+
private finishedRunning: { [id: string]: string } = {}
83+
private startedRunning: Set<string> = new Set()
7284

7385
constructor(dvcRoot: string, workspaceState: Memento) {
7486
super(dvcRoot, workspaceState)
@@ -107,16 +119,15 @@ export class ExperimentsModel extends ModelWithPersistence {
107119
branches,
108120
experimentsByBranch,
109121
checkpointsByTip,
110-
hasRunning
122+
runningExperiments
111123
} = collectExperiments(data)
112124

113125
this.workspace = workspace
114126
this.branches = branches
115127
this.experimentsByBranch = experimentsByBranch
116128
this.checkpointsByTip = checkpointsByTip
117-
this.hasRunning = hasRunning
118129

119-
this.setColoredStatus()
130+
this.setColoredStatus(runningExperiments)
120131
}
121132

122133
public toggleStars(ids: string[]) {
@@ -151,7 +162,17 @@ export class ExperimentsModel extends ModelWithPersistence {
151162
}
152163

153164
public hasRunningExperiment() {
154-
return this.hasRunning
165+
return this.running.length > 0
166+
}
167+
168+
public setRevisionCollected(revisions: string[]) {
169+
this.getFlattenedExperiments()
170+
.filter(({ label }) => revisions.includes(label))
171+
.map(({ id }) => {
172+
if (this.finishedRunning[id]) {
173+
delete this.finishedRunning[id]
174+
}
175+
})
155176
}
156177

157178
public canSelect() {
@@ -420,6 +441,10 @@ export class ExperimentsModel extends ModelWithPersistence {
420441
}))
421442
}
422443

444+
public getFinishedExperiments() {
445+
return this.finishedRunning
446+
}
447+
423448
private getSubRows(experiments: Experiment[], filters = this.getFilters()) {
424449
return experiments
425450
.map(experiment => {
@@ -510,7 +535,9 @@ export class ExperimentsModel extends ModelWithPersistence {
510535
)
511536
}
512537

513-
private setColoredStatus() {
538+
private setColoredStatus(runningExperiments: RunningExperiment[]) {
539+
this.setRunning(runningExperiments)
540+
514541
if (this.useFiltersForSelection) {
515542
this.setSelectedToFilters()
516543
return
@@ -520,14 +547,34 @@ export class ExperimentsModel extends ModelWithPersistence {
520547
this.checkpointsByTip,
521548
this.experimentsByBranch,
522549
this.coloredStatus,
523-
this.availableColors
550+
this.availableColors,
551+
this.startedRunning,
552+
this.finishedRunning
524553
)
554+
this.startedRunning = new Set()
525555

526556
this.setColors(coloredStatus, availableColors)
527557

528558
this.persistStatus()
529559
}
530560

561+
private setRunning(stillRunning: RunningExperiment[]) {
562+
this.startedRunning = collectStartedRunningExperiments(
563+
this.running,
564+
stillRunning
565+
)
566+
567+
this.finishedRunning = collectFinishedRunningExperiments(
568+
{ ...this.finishedRunning },
569+
this.getFlattenedExperiments(),
570+
this.running,
571+
stillRunning,
572+
this.coloredStatus
573+
)
574+
575+
this.running = stillRunning
576+
}
577+
531578
private setColors(coloredStatus: ColoredStatus, availableColors: Color[]) {
532579
this.coloredStatus = coloredStatus
533580
this.availableColors = availableColors

0 commit comments

Comments
 (0)