Skip to content

Commit 2aacfe2

Browse files
Merge pull request #52 from HumairAK/RHOAIENG-7692
UPSTREAM: <carry>: add last_run_creation
2 parents f3fbc2c + bf77909 commit 2aacfe2

File tree

12 files changed

+466
-269
lines changed

12 files changed

+466
-269
lines changed

backend/api/v2beta1/experiment.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ message Experiment {
9999

100100
// Output. Specifies whether this experiment is in archived or available state.
101101
StorageState storage_state = 6;
102+
103+
// Output. The creation time of the last run in this experiment.
104+
google.protobuf.Timestamp last_run_created_at = 7;
102105
}
103106

104107
message CreateExperimentRequest {

backend/api/v2beta1/go_client/experiment.pb.go

Lines changed: 143 additions & 128 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/api/v2beta1/go_http_client/experiment_model/v2beta1_experiment.go

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/api/v2beta1/swagger/experiment.swagger.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@
227227
"storage_state": {
228228
"$ref": "#/definitions/v2beta1ExperimentStorageState",
229229
"description": "Output. Specifies whether this experiment is in archived or available state."
230+
},
231+
"last_run_created_at": {
232+
"type": "string",
233+
"format": "date-time",
234+
"description": "Output. The time the created time of the last run in this experiment."
230235
}
231236
}
232237
},

backend/api/v2beta1/swagger/kfp_api_single_file.swagger.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,11 @@
15231523
"storage_state": {
15241524
"$ref": "#/definitions/v2beta1ExperimentStorageState",
15251525
"description": "Output. Specifies whether this experiment is in archived or available state."
1526+
},
1527+
"last_run_created_at": {
1528+
"type": "string",
1529+
"format": "date-time",
1530+
"description": "Output. The time the created time of the last run in this experiment."
15261531
}
15271532
}
15281533
},

backend/src/apiserver/model/experiment.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
package model
1616

1717
type Experiment struct {
18-
UUID string `gorm:"column:UUID; not null; primary_key;"`
19-
Name string `gorm:"column:Name; not null; unique_index:idx_name_namespace;"`
20-
Description string `gorm:"column:Description; not null;"`
21-
CreatedAtInSec int64 `gorm:"column:CreatedAtInSec; not null;"`
22-
Namespace string `gorm:"column:Namespace; not null; unique_index:idx_name_namespace;"`
23-
StorageState StorageState `gorm:"column:StorageState; not null;"`
18+
UUID string `gorm:"column:UUID; not null; primary_key;"`
19+
Name string `gorm:"column:Name; not null; unique_index:idx_name_namespace;"`
20+
Description string `gorm:"column:Description; not null;"`
21+
CreatedAtInSec int64 `gorm:"column:CreatedAtInSec; not null;"`
22+
LastRunCreatedAtInSec int64 `gorm:"column:LastRunCreatedAtInSec; not null;"`
23+
Namespace string `gorm:"column:Namespace; not null; unique_index:idx_name_namespace;"`
24+
StorageState StorageState `gorm:"column:StorageState; not null;"`
2425
}
2526

2627
// Note: Experiment.StorageState can have values: "STORAGE_STATE_UNSPECIFIED", "AVAILABLE" or "ARCHIVED"
@@ -44,14 +45,15 @@ func (e *Experiment) DefaultSortField() string {
4445
}
4546

4647
var experimentAPIToModelFieldMap = map[string]string{
47-
"id": "UUID", // v1beta1 API
48-
"experiment_id": "UUID", // v2beta1 API
49-
"name": "Name", // v1beta1 API
50-
"display_name": "Name", // v2beta1 API
51-
"created_at": "CreatedAtInSec",
52-
"description": "Description",
53-
"namespace": "Namespace", // v2beta1 API
54-
"storage_state": "StorageState",
48+
"id": "UUID", // v1beta1 API
49+
"experiment_id": "UUID", // v2beta1 API
50+
"name": "Name", // v1beta1 API
51+
"display_name": "Name", // v2beta1 API
52+
"created_at": "CreatedAtInSec",
53+
"last_run_created_at": "LastRunCreatedAtInSec", // v2beta1 API
54+
"description": "Description",
55+
"namespace": "Namespace", // v2beta1 API
56+
"storage_state": "StorageState",
5557
}
5658

5759
// APIToModelFieldMap returns a map from API names to field names for model
@@ -80,6 +82,8 @@ func (e *Experiment) GetFieldValue(name string) interface{} {
8082
return e.Name
8183
case "CreatedAtInSec":
8284
return e.CreatedAtInSec
85+
case "LastRunCreatedAtInSec":
86+
return e.LastRunCreatedAtInSec
8387
case "Description":
8488
return e.Description
8589
case "Namespace":

backend/src/apiserver/resource/resource_manager.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,13 @@ func (r *ResourceManager) CreateRun(ctx context.Context, run *model.Run) (*model
550550
if err != nil {
551551
return nil, util.Wrap(err, "Failed to create a run")
552552
}
553+
554+
// Upon run creation, update owning experiment
555+
err = r.experimentStore.UpdateLastRun(newRun)
556+
if err != nil {
557+
return nil, util.Wrap(err, fmt.Sprintf("Failed to update last_run_created_at in experiment %s for run %s", newRun.ExperimentId, newRun.UUID))
558+
}
559+
553560
return newRun, nil
554561
}
555562

@@ -1256,6 +1263,10 @@ func (r *ResourceManager) ReportWorkflowResource(ctx context.Context, execSpec u
12561263
} else {
12571264
runId = run.UUID
12581265
}
1266+
// Upon run creation, update owning experiment
1267+
if updateError = r.experimentStore.UpdateLastRun(run); updateError != nil {
1268+
return nil, util.Wrapf(updateError, "Failed to report a workflow for existing run %s during updating the owning experiment.", runId)
1269+
}
12591270
}
12601271
if execStatus.IsInFinalState() {
12611272
err := addWorkflowLabel(ctx, r.getWorkflowClient(execSpec.ExecutionNamespace()), execSpec.ExecutionName(), util.LabelKeyWorkflowPersistedFinalState, "true")

backend/src/apiserver/server/api_converter.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@ func toApiExperiment(experiment *model.Experiment) *apiv2beta1.Experiment {
113113
storageState = apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["STORAGE_STATE_UNSPECIFIED"])
114114
}
115115
return &apiv2beta1.Experiment{
116-
ExperimentId: experiment.UUID,
117-
DisplayName: experiment.Name,
118-
Description: experiment.Description,
119-
CreatedAt: &timestamp.Timestamp{Seconds: experiment.CreatedAtInSec},
120-
Namespace: experiment.Namespace,
121-
StorageState: storageState,
116+
ExperimentId: experiment.UUID,
117+
DisplayName: experiment.Name,
118+
Description: experiment.Description,
119+
CreatedAt: &timestamp.Timestamp{Seconds: experiment.CreatedAtInSec},
120+
LastRunCreatedAt: &timestamp.Timestamp{Seconds: experiment.LastRunCreatedAtInSec},
121+
Namespace: experiment.Namespace,
122+
StorageState: storageState,
122123
}
123124
}
124125

backend/src/apiserver/server/api_converter_test.go

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,77 +1974,87 @@ func TestToApiExperimentsV1(t *testing.T) {
19741974

19751975
func TestToApiExperiments(t *testing.T) {
19761976
exp1 := &model.Experiment{
1977-
UUID: "exp1",
1978-
CreatedAtInSec: 1,
1979-
Name: "experiment1",
1980-
Description: "My name is experiment1",
1981-
StorageState: "AVAILABLE",
1977+
UUID: "exp1",
1978+
CreatedAtInSec: 1,
1979+
LastRunCreatedAtInSec: 1,
1980+
Name: "experiment1",
1981+
Description: "My name is experiment1",
1982+
StorageState: "AVAILABLE",
19821983
}
19831984
exp2 := &model.Experiment{
1984-
UUID: "exp2",
1985-
CreatedAtInSec: 2,
1986-
Name: "experiment2",
1987-
Description: "My name is experiment2",
1988-
StorageState: "ARCHIVED",
1985+
UUID: "exp2",
1986+
CreatedAtInSec: 2,
1987+
LastRunCreatedAtInSec: 2,
1988+
Name: "experiment2",
1989+
Description: "My name is experiment2",
1990+
StorageState: "ARCHIVED",
19891991
}
19901992
exp3 := &model.Experiment{
1991-
UUID: "exp3",
1992-
CreatedAtInSec: 1,
1993-
Name: "experiment3",
1994-
Description: "experiment3 was created using V1 APIV1BETA1",
1995-
StorageState: "STORAGESTATE_AVAILABLE",
1993+
UUID: "exp3",
1994+
CreatedAtInSec: 1,
1995+
LastRunCreatedAtInSec: 1,
1996+
Name: "experiment3",
1997+
Description: "experiment3 was created using V1 APIV1BETA1",
1998+
StorageState: "STORAGESTATE_AVAILABLE",
19961999
}
19972000
exp4 := &model.Experiment{
1998-
UUID: "exp4",
1999-
CreatedAtInSec: 2,
2000-
Name: "experiment4",
2001-
Description: "experiment4 was created using V1 APIV1BETA1",
2002-
StorageState: "STORAGESTATE_ARCHIVED",
2001+
UUID: "exp4",
2002+
CreatedAtInSec: 2,
2003+
LastRunCreatedAtInSec: 2,
2004+
Name: "experiment4",
2005+
Description: "experiment4 was created using V1 APIV1BETA1",
2006+
StorageState: "STORAGESTATE_ARCHIVED",
20032007
}
20042008
exp5 := &model.Experiment{
2005-
UUID: "exp5",
2006-
CreatedAtInSec: 1,
2007-
Name: "experiment5",
2008-
Description: "My name is experiment5",
2009-
StorageState: "this is invalid storage state",
2009+
UUID: "exp5",
2010+
CreatedAtInSec: 1,
2011+
LastRunCreatedAtInSec: 1,
2012+
Name: "experiment5",
2013+
Description: "My name is experiment5",
2014+
StorageState: "this is invalid storage state",
20102015
}
20112016
apiExps := toApiExperiments([]*model.Experiment{exp1, exp2, exp3, exp4, nil, exp5})
20122017
expectedApiExps := []*apiv2beta1.Experiment{
20132018
{
2014-
ExperimentId: "exp1",
2015-
DisplayName: "experiment1",
2016-
Description: "My name is experiment1",
2017-
CreatedAt: &timestamp.Timestamp{Seconds: 1},
2018-
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["AVAILABLE"]),
2019+
ExperimentId: "exp1",
2020+
DisplayName: "experiment1",
2021+
Description: "My name is experiment1",
2022+
CreatedAt: &timestamp.Timestamp{Seconds: 1},
2023+
LastRunCreatedAt: &timestamp.Timestamp{Seconds: 1},
2024+
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["AVAILABLE"]),
20192025
},
20202026
{
2021-
ExperimentId: "exp2",
2022-
DisplayName: "experiment2",
2023-
Description: "My name is experiment2",
2024-
CreatedAt: &timestamp.Timestamp{Seconds: 2},
2025-
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["ARCHIVED"]),
2027+
ExperimentId: "exp2",
2028+
DisplayName: "experiment2",
2029+
Description: "My name is experiment2",
2030+
CreatedAt: &timestamp.Timestamp{Seconds: 2},
2031+
LastRunCreatedAt: &timestamp.Timestamp{Seconds: 2},
2032+
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["ARCHIVED"]),
20262033
},
20272034
{
2028-
ExperimentId: "exp3",
2029-
DisplayName: "experiment3",
2030-
Description: "experiment3 was created using V1 APIV1BETA1",
2031-
CreatedAt: &timestamp.Timestamp{Seconds: 1},
2032-
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["AVAILABLE"]),
2035+
ExperimentId: "exp3",
2036+
DisplayName: "experiment3",
2037+
Description: "experiment3 was created using V1 APIV1BETA1",
2038+
CreatedAt: &timestamp.Timestamp{Seconds: 1},
2039+
LastRunCreatedAt: &timestamp.Timestamp{Seconds: 1},
2040+
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["AVAILABLE"]),
20332041
},
20342042
{
2035-
ExperimentId: "exp4",
2036-
DisplayName: "experiment4",
2037-
Description: "experiment4 was created using V1 APIV1BETA1",
2038-
CreatedAt: &timestamp.Timestamp{Seconds: 2},
2039-
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["ARCHIVED"]),
2043+
ExperimentId: "exp4",
2044+
DisplayName: "experiment4",
2045+
Description: "experiment4 was created using V1 APIV1BETA1",
2046+
CreatedAt: &timestamp.Timestamp{Seconds: 2},
2047+
LastRunCreatedAt: &timestamp.Timestamp{Seconds: 2},
2048+
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["ARCHIVED"]),
20402049
},
20412050
{},
20422051
{
2043-
ExperimentId: "exp5",
2044-
DisplayName: "experiment5",
2045-
Description: "My name is experiment5",
2046-
CreatedAt: &timestamp.Timestamp{Seconds: 1},
2047-
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["STORAGE_STATE_UNSPECIFIED"]),
2052+
ExperimentId: "exp5",
2053+
DisplayName: "experiment5",
2054+
Description: "My name is experiment5",
2055+
CreatedAt: &timestamp.Timestamp{Seconds: 1},
2056+
LastRunCreatedAt: &timestamp.Timestamp{Seconds: 1},
2057+
StorageState: apiv2beta1.Experiment_StorageState(apiv2beta1.Experiment_StorageState_value["STORAGE_STATE_UNSPECIFIED"]),
20482058
},
20492059
}
20502060
assert.Equal(t, expectedApiExps, apiExps)

0 commit comments

Comments
 (0)