Skip to content

Commit

Permalink
[ProjectSummaries] Add runs_completed_recent_count (#5482)
Browse files Browse the repository at this point in the history
  • Loading branch information
roei3000b committed May 2, 2024
1 parent fea108d commit 017ebda
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 5 deletions.
1 change: 1 addition & 0 deletions mlrun/common/schemas/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class ProjectSummary(pydantic.BaseModel):
files_count: int
feature_sets_count: int
models_count: int
runs_completed_recent_count: int
runs_failed_recent_count: int
runs_running_count: int
schedules_count: int
Expand Down
7 changes: 7 additions & 0 deletions server/api/crud/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ async def generate_projects_summaries(
project_to_schedule_count,
project_to_feature_set_count,
project_to_models_count,
project_to_recent_completed_runs_count,
project_to_recent_failed_runs_count,
project_to_running_runs_count,
project_to_running_pipelines_count,
Expand All @@ -309,6 +310,9 @@ async def generate_projects_summaries(
schedules_count=project_to_schedule_count.get(project, 0),
feature_sets_count=project_to_feature_set_count.get(project, 0),
models_count=project_to_models_count.get(project, 0),
runs_completed_recent_count=project_to_recent_completed_runs_count.get(
project, 0
),
runs_failed_recent_count=project_to_recent_failed_runs_count.get(
project, 0
),
Expand All @@ -329,6 +333,7 @@ async def _get_project_resources_counters(
dict[str, int],
dict[str, int],
dict[str, int],
dict[str, int],
dict[str, typing.Union[int, None]],
]:
now = datetime.datetime.now()
Expand All @@ -350,6 +355,7 @@ async def _get_project_resources_counters(
project_to_schedule_count,
project_to_feature_set_count,
project_to_models_count,
project_to_recent_completed_runs_count,
project_to_recent_failed_runs_count,
project_to_running_runs_count,
) = results[0]
Expand All @@ -359,6 +365,7 @@ async def _get_project_resources_counters(
project_to_schedule_count,
project_to_feature_set_count,
project_to_models_count,
project_to_recent_completed_runs_count,
project_to_recent_failed_runs_count,
project_to_running_runs_count,
project_to_running_pipelines_count,
Expand Down
1 change: 1 addition & 0 deletions server/api/db/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ async def get_project_resources_counters(
dict[str, int],
dict[str, int],
dict[str, int],
dict[str, int],
]:
pass

Expand Down
32 changes: 30 additions & 2 deletions server/api/db/sqldb/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -2188,6 +2188,7 @@ async def get_project_resources_counters(
dict[str, int],
dict[str, int],
dict[str, int],
dict[str, int],
]:
results = await asyncio.gather(
fastapi.concurrency.run_in_threadpool(
Expand Down Expand Up @@ -2217,6 +2218,7 @@ async def get_project_resources_counters(
project_to_feature_set_count,
project_to_models_count,
(
project_to_recent_completed_runs_count,
project_to_recent_failed_runs_count,
project_to_running_runs_count,
),
Expand All @@ -2226,6 +2228,7 @@ async def get_project_resources_counters(
project_to_schedule_count,
project_to_feature_set_count,
project_to_models_count,
project_to_recent_completed_runs_count,
project_to_recent_failed_runs_count,
project_to_running_runs_count,
)
Expand Down Expand Up @@ -2299,7 +2302,11 @@ def _calculate_files_counters(self, session) -> dict[str, int]:

def _calculate_runs_counters(
self, session
) -> tuple[dict[str, int], dict[str, int]]:
) -> tuple[
dict[str, int],
dict[str, int],
dict[str, int],
]:
running_runs_count_per_project = (
session.query(Run.project, func.count(distinct(Run.name)))
.filter(
Expand Down Expand Up @@ -2330,7 +2337,28 @@ def _calculate_runs_counters(
project_to_recent_failed_runs_count = {
result[0]: result[1] for result in recent_failed_runs_count_per_project
}
return project_to_recent_failed_runs_count, project_to_running_runs_count

recent_completed_runs_count_per_project = (
session.query(Run.project, func.count(distinct(Run.name)))
.filter(
Run.state.in_(
[
mlrun.runtimes.constants.RunStates.completed,
]
)
)
.filter(Run.start_time >= one_day_ago)
.group_by(Run.project)
.all()
)
project_to_recent_completed_runs_count = {
result[0]: result[1] for result in recent_completed_runs_count_per_project
}
return (
project_to_recent_completed_runs_count,
project_to_recent_failed_runs_count,
project_to_running_runs_count,
)

async def generate_projects_summaries(
self, session: Session, projects: list[str]
Expand Down
30 changes: 28 additions & 2 deletions tests/api/api/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,25 @@ def test_list_and_get_project_summaries(
)

# create completed runs for the project to make sure we're not mistakenly counting them
_create_runs(client, project_name, 2, mlrun.runtimes.constants.RunStates.completed)
two_days_ago = datetime.datetime.now() - datetime.timedelta(hours=48)
_create_runs(
client,
project_name,
2,
mlrun.runtimes.constants.RunStates.completed,
two_days_ago,
)

# create completed runs for the project for less than 24 hours ago
runs_completed_recent_count = 10
one_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1)
_create_runs(
client,
project_name,
runs_completed_recent_count,
mlrun.runtimes.constants.RunStates.completed,
one_hour_ago,
)

# create failed runs for the project for less than 24 hours ago
recent_failed_runs_count = 6
Expand Down Expand Up @@ -371,13 +389,14 @@ def test_list_and_get_project_summaries(
)
for index, project_summary in enumerate(project_summaries_output.project_summaries):
if project_summary.name == empty_project_name:
_assert_project_summary(project_summary, 0, 0, 0, 0, 0, 0, 0)
_assert_project_summary(project_summary, 0, 0, 0, 0, 0, 0, 0, 0)
elif project_summary.name == project_name:
_assert_project_summary(
project_summary,
files_count,
feature_sets_count,
models_count,
runs_completed_recent_count,
recent_failed_runs_count + recent_aborted_runs_count,
running_runs_count,
schedules_count,
Expand All @@ -394,6 +413,7 @@ def test_list_and_get_project_summaries(
files_count,
feature_sets_count,
models_count,
runs_completed_recent_count,
recent_failed_runs_count + recent_aborted_runs_count,
running_runs_count,
schedules_count,
Expand Down Expand Up @@ -438,6 +458,7 @@ def test_list_project_summaries_different_installation_modes(
0,
0,
0,
0,
)

# Enterprise installation configuration pre 3.4.0
Expand All @@ -460,6 +481,7 @@ def test_list_project_summaries_different_installation_modes(
0,
0,
0,
0,
)

# Kubernetes installation configuration (mlrun-kit)
Expand All @@ -482,6 +504,7 @@ def test_list_project_summaries_different_installation_modes(
0,
0,
0,
0,
)

# Docker installation configuration
Expand All @@ -504,6 +527,7 @@ def test_list_project_summaries_different_installation_modes(
0,
0,
0,
0,
)


Expand Down Expand Up @@ -1543,6 +1567,7 @@ def _assert_project_summary(
files_count: int,
feature_sets_count: int,
models_count: int,
runs_completed_recent_count,
runs_failed_recent_count: int,
runs_running_count: int,
schedules_count: int,
Expand All @@ -1551,6 +1576,7 @@ def _assert_project_summary(
assert project_summary.files_count == files_count
assert project_summary.feature_sets_count == feature_sets_count
assert project_summary.models_count == models_count
assert project_summary.runs_completed_recent_count == runs_completed_recent_count
assert project_summary.runs_failed_recent_count == runs_failed_recent_count
assert project_summary.runs_running_count == runs_running_count
assert project_summary.schedules_count == schedules_count
Expand Down
3 changes: 2 additions & 1 deletion tests/api/utils/projects/test_follower_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ async def test_list_project_summaries(
runs_failed_recent_count=7,
runs_running_count=8,
schedules_count=1,
runs_completed_recent_count=9,
pipelines_running_count=2,
)
server.api.crud.Projects().generate_projects_summaries = unittest.mock.Mock(
Expand Down Expand Up @@ -451,7 +452,7 @@ async def test_list_project_summaries_fails_to_list_pipeline_runs(
)

server.api.utils.singletons.db.get_db().get_project_resources_counters = (
unittest.mock.AsyncMock(return_value=tuple({project_name: i} for i in range(6)))
unittest.mock.AsyncMock(return_value=tuple({project_name: i} for i in range(7)))
)
project_summaries = await projects_follower.list_project_summaries(db)
assert len(project_summaries.project_summaries) == 1
Expand Down

0 comments on commit 017ebda

Please sign in to comment.