Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Sync from GitHub via hub-sync
Browse files
src/app/[org]/[dataset]/[episode]/fetch-data.ts
CHANGED
|
@@ -221,12 +221,15 @@ function pickProgressColumn(rows: Record<string, unknown>[]): string | null {
|
|
| 221 |
return null;
|
| 222 |
}
|
| 223 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
async function loadEpisodeProgressGroup(
|
| 225 |
repoId: string,
|
| 226 |
version: string,
|
| 227 |
episodeId: number,
|
| 228 |
-
|
| 229 |
-
): Promise<ChartRow[] | null> {
|
| 230 |
for (const progressPath of PROGRESS_PARQUET_CANDIDATES) {
|
| 231 |
const progressUrl = buildVersionedUrl(repoId, version, progressPath);
|
| 232 |
try {
|
|
@@ -269,13 +272,15 @@ async function loadEpisodeProgressGroup(
|
|
| 269 |
);
|
| 270 |
const progressKey = buildProgressSeriesKey(progressColumn);
|
| 271 |
const denominator = Math.max(sampledPoints.length - 1, 1);
|
| 272 |
-
const duration = Math.max(episodeDuration, 0);
|
| 273 |
|
| 274 |
-
return
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
|
|
|
|
|
|
|
|
|
| 279 |
} catch {
|
| 280 |
// Optional file: ignore and try next candidate.
|
| 281 |
}
|
|
@@ -310,11 +315,19 @@ export async function getEpisodeData(
|
|
| 310 |
);
|
| 311 |
}
|
| 312 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
console.time(`[perf] getEpisodeData (${version})`);
|
| 314 |
-
const result =
|
| 315 |
version === "v3.0"
|
| 316 |
-
?
|
| 317 |
-
:
|
|
|
|
|
|
|
| 318 |
console.timeEnd(`[perf] getEpisodeData (${version})`);
|
| 319 |
|
| 320 |
// Extract camera resolutions from features
|
|
@@ -336,14 +349,11 @@ export async function getEpisodeData(
|
|
| 336 |
cameras,
|
| 337 |
};
|
| 338 |
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
);
|
| 345 |
-
if (progressGroup && progressGroup.length > 0) {
|
| 346 |
-
result.chartDataGroups = [...result.chartDataGroups, progressGroup];
|
| 347 |
}
|
| 348 |
|
| 349 |
return result;
|
|
|
|
| 221 |
return null;
|
| 222 |
}
|
| 223 |
|
| 224 |
+
// Returns a builder that, given the episode's final duration, produces the
|
| 225 |
+
// scaled progress chart group. Splitting "fetch the parquet" from "scale by
|
| 226 |
+
// duration" lets the caller kick off the fetch in parallel with the main
|
| 227 |
+
// episode-data fetch instead of waiting on a sequential await.
|
| 228 |
async function loadEpisodeProgressGroup(
|
| 229 |
repoId: string,
|
| 230 |
version: string,
|
| 231 |
episodeId: number,
|
| 232 |
+
): Promise<((episodeDuration: number) => ChartRow[]) | null> {
|
|
|
|
| 233 |
for (const progressPath of PROGRESS_PARQUET_CANDIDATES) {
|
| 234 |
const progressUrl = buildVersionedUrl(repoId, version, progressPath);
|
| 235 |
try {
|
|
|
|
| 272 |
);
|
| 273 |
const progressKey = buildProgressSeriesKey(progressColumn);
|
| 274 |
const denominator = Math.max(sampledPoints.length - 1, 1);
|
|
|
|
| 275 |
|
| 276 |
+
return (episodeDuration: number) => {
|
| 277 |
+
const duration = Math.max(episodeDuration, 0);
|
| 278 |
+
return sampledPoints.map((point, idx) => ({
|
| 279 |
+
timestamp:
|
| 280 |
+
sampledPoints.length === 1 ? 0 : (idx / denominator) * duration,
|
| 281 |
+
[progressKey]: point.progress,
|
| 282 |
+
}));
|
| 283 |
+
};
|
| 284 |
} catch {
|
| 285 |
// Optional file: ignore and try next candidate.
|
| 286 |
}
|
|
|
|
| 315 |
);
|
| 316 |
}
|
| 317 |
|
| 318 |
+
// Run the main episode-data fetch and the optional progress parquet
|
| 319 |
+
// in parallel. Previously they ran serially: the progress fetch was
|
| 320 |
+
// gated on result.duration even though it only used duration to scale
|
| 321 |
+
// timestamps at the end. Now loadEpisodeProgressGroup returns a
|
| 322 |
+
// builder we apply once both promises settle.
|
| 323 |
+
// Vercel rule: async-parallel.
|
| 324 |
console.time(`[perf] getEpisodeData (${version})`);
|
| 325 |
+
const [result, progressBuilder] = await Promise.all([
|
| 326 |
version === "v3.0"
|
| 327 |
+
? getEpisodeDataV3(repoId, version, info, episodeId)
|
| 328 |
+
: getEpisodeDataV2(repoId, version, info, episodeId),
|
| 329 |
+
loadEpisodeProgressGroup(repoId, version, episodeId),
|
| 330 |
+
]);
|
| 331 |
console.timeEnd(`[perf] getEpisodeData (${version})`);
|
| 332 |
|
| 333 |
// Extract camera resolutions from features
|
|
|
|
| 349 |
cameras,
|
| 350 |
};
|
| 351 |
|
| 352 |
+
if (progressBuilder) {
|
| 353 |
+
const progressGroup = progressBuilder(result.duration);
|
| 354 |
+
if (progressGroup.length > 0) {
|
| 355 |
+
result.chartDataGroups = [...result.chartDataGroups, progressGroup];
|
| 356 |
+
}
|
|
|
|
|
|
|
|
|
|
| 357 |
}
|
| 358 |
|
| 359 |
return result;
|