Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion backend/kernelCI_app/apps.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import os
import sys
import threading

from django.apps import AppConfig


Expand All @@ -6,4 +10,20 @@ class KernelciAppConfig(AppConfig):
name = "kernelCI_app"

def ready(self) -> None:
return super().ready()
super().ready()
is_server = (
os.path.basename(sys.argv[0]) == "gunicorn" or "runserver" in sys.argv
)
if not is_server:
return
if "runserver" in sys.argv and os.environ.get("RUN_MAIN") != "true":
return

from django.core.cache import cache

from kernelCI_app.queries.notifications import warm_metrics_cache

# Single-flight via atomic Redis add: only one worker warms per deploy.
if not cache.add("metrics_startup_warm_lock", 1, timeout=600):
return
threading.Thread(target=warm_metrics_cache, daemon=True).start()
19 changes: 13 additions & 6 deletions backend/kernelCI_app/queries/notifications.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sys
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime, time, timedelta, timezone
from datetime import date, datetime, time, timedelta, timezone
from typing import Any

from django.db import connection, connections
Expand Down Expand Up @@ -749,6 +749,12 @@ def query_fetchall_work(
return rows


def last_saturday(today: date | None = None) -> date:
"""Most recent Saturday UTC (today when today is Saturday)."""
day = today or datetime.now(timezone.utc).date()
return day - timedelta(days=(day.weekday() + 2) % 7)


def interval_params(start_days_ago: int, end_days_ago: int) -> dict[str, str]:
"""Build [start_date, end_date) bounds from UTC day offsets."""
today = datetime.now(timezone.utc).date()
Expand Down Expand Up @@ -1068,16 +1074,17 @@ def get_metrics_data(


def warm_metrics_cache() -> None:
today = datetime.now(timezone.utc).date()
end_days_ago = (today - last_saturday(today)).days
for period_days in METRICS_CACHE_WARM_PERIODS:
out(
"Warming metrics cache for "
f"{period_days}-day period "
f"(start_days_ago={period_days}, end_days_ago=0)"
f"Warming metrics cache for {period_days}-day Sat-Fri period "
f"(end_days_ago={end_days_ago})"
)
try:
get_metrics_data(
start_days_ago=period_days,
end_days_ago=0,
start_days_ago=end_days_ago + period_days,
end_days_ago=end_days_ago,
use_cache=False,
cache_timeout=METRICS_CACHE_WARM_TIMEOUT,
)
Expand Down
7 changes: 1 addition & 6 deletions backend/kernelCI_app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
)

from kernelCI_app import views
from kernelCI_app.queries.notifications import METRICS_CACHE_TIMEOUT


def view_cache(view, timeout: int = settings.CACHE_TIMEOUT):
Expand Down Expand Up @@ -180,9 +179,5 @@ def view_cache(view, timeout: int = settings.CACHE_TIMEOUT):
path("proxy/", views.ProxyView.as_view(), name="proxyView"),
path("origins/", views.OriginsView.as_view(), name="originsView"),
path("tree-report/", views.TreeReport.as_view(), name="treeReportView"),
path(
"metrics/",
view_cache(views.MetricsView, timeout=METRICS_CACHE_TIMEOUT),
name="metricsView",
),
path("metrics/", views.MetricsView.as_view(), name="metricsView"),
]
7 changes: 2 additions & 5 deletions dashboard/src/pages/Metrics/MetricsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -551,11 +551,8 @@ function LabsSection({ labs }: { labs: LabData[] }): JSX.Element {
const getMetricsQueryParams = (
activeDays: number,
): { startDaysAgo: number; endDaysAgo: number } => {
const today = new Date();
const weekEndDaysAgo = (today.getUTCDay() + 1) % DAYS_IN_WEEK;
const endDaysAgo = Math.max(weekEndDaysAgo - 1, 0);
const startDaysAgo = endDaysAgo + activeDays;
return { startDaysAgo, endDaysAgo };
const endDaysAgo = (new Date().getUTCDay() + 1) % DAYS_IN_WEEK;
return { startDaysAgo: endDaysAgo + activeDays, endDaysAgo };
};

export const MetricsPage = (): JSX.Element => {
Expand Down
Loading