mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
fix(workouts): start the windowed workout read after the plain reads beside it
The windowed reader is async, so a Promise.all that listed it first held a rejected promise of it whenever a later element threw while the array was built, and nobody handled that rejection. It now comes last in each of those arrays.
This commit is contained in:
1 parent
cec7ce2ad5
commit
6c4c097517
6 files changed
+34
-29
No files matched your search
@@ -909,7 +909,11 @@ async function assessmentsPart(frame: DayFrame): Promise<SectionPart> {
|
||||
/* ─── workouts, cycle ─────────────────────────────────────────────────────── */
|
||||
|
||||
async function workoutsPart(frame: DayFrame): Promise<SectionPart> {
|
||||
const [stored, account] = await Promise.all([
|
||||
const [account, stored] = await Promise.all([
|
||||
prisma.user.findUnique({
|
||||
where: { id: frame.userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
}),
|
||||
// The windowed reader orders the rows itself.
|
||||
readWorkoutsAroundRange(
|
||||
{ from: frame.dayStart, to: frame.dayEnd },
|
||||
@@ -919,10 +923,6 @@ async function workoutsPart(frame: DayFrame): Promise<SectionPart> {
|
||||
select: WORKOUT_PICK_SELECT,
|
||||
}),
|
||||
),
|
||||
prisma.user.findUnique({
|
||||
where: { id: frame.userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
}),
|
||||
]);
|
||||
// One session synced by two services is one workout on the day, as in the
|
||||
// workout list it links to, a twin across midnight included.
|
||||
|
||||
@@ -1260,15 +1260,7 @@ export async function fetchTrainingSeries(
|
||||
tz: string,
|
||||
since: Date,
|
||||
): Promise<NamedSeries[]> {
|
||||
const [workouts, account, trimp] = await Promise.all([
|
||||
readWorkoutsAroundRange({ from: since, to: null }, (bounds) =>
|
||||
prisma.workout.findMany({
|
||||
where: { userId, startedAt: bounds },
|
||||
orderBy: [{ startedAt: "asc" }, { id: "asc" }],
|
||||
take: WORKOUT_READ_CAP,
|
||||
select: WORKOUT_PICK_SELECT,
|
||||
}),
|
||||
),
|
||||
const [account, trimp, workouts] = await Promise.all([
|
||||
prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
@@ -1280,6 +1272,14 @@ export async function fetchTrainingSeries(
|
||||
take: 1000,
|
||||
select: { day: true, dayTrimp: true },
|
||||
}),
|
||||
readWorkoutsAroundRange({ from: since, to: null }, (bounds) =>
|
||||
prisma.workout.findMany({
|
||||
where: { userId, startedAt: bounds },
|
||||
orderBy: [{ startedAt: "asc" }, { id: "asc" }],
|
||||
take: WORKOUT_READ_CAP,
|
||||
select: WORKOUT_PICK_SELECT,
|
||||
}),
|
||||
),
|
||||
]);
|
||||
const sessions = canonicalWorkoutsInRange(
|
||||
workouts,
|
||||
|
||||
@@ -539,7 +539,11 @@ export async function readWorkoutsBlock(
|
||||
now: number,
|
||||
): Promise<AggregatedFeatures["workouts"] | undefined> {
|
||||
const since = new Date(now - WORKOUT_WINDOW_DAYS * MS_PER_DAY);
|
||||
const [stored, account] = await Promise.all([
|
||||
const [account, stored] = await Promise.all([
|
||||
prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
}),
|
||||
readWorkoutsAroundRange({ from: since, to: null }, (bounds) =>
|
||||
prisma.workout.findMany({
|
||||
where: { userId, startedAt: bounds },
|
||||
@@ -555,10 +559,6 @@ export async function readWorkoutsBlock(
|
||||
},
|
||||
}),
|
||||
),
|
||||
prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
}),
|
||||
]);
|
||||
// One session synced by two services (or re-sent by HealthKit) is one
|
||||
// workout: the same collapse the workout list applies, so the count and the
|
||||
|
||||
@@ -432,7 +432,11 @@ export async function computeStrainScore(
|
||||
// The day's workouts + their HR series, with the session identity the
|
||||
// cross-source picker needs: one run recorded by the watch and synced again
|
||||
// through a second service is one training impulse, not two.
|
||||
const [workouts, account] = await Promise.all([
|
||||
const [account, workouts] = await Promise.all([
|
||||
prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
}),
|
||||
// Read through the windowed reader: a session whose twin lies across
|
||||
// midnight is counted once, on the day the list shows it.
|
||||
readWorkoutsAroundRange({ from: dayStart, to: dayEnd }, (bounds) =>
|
||||
@@ -450,10 +454,6 @@ export async function computeStrainScore(
|
||||
take: 100,
|
||||
}),
|
||||
),
|
||||
prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
}),
|
||||
]);
|
||||
|
||||
// The watch and the phone relay (or a ring) both write the day's active
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
* surfaces then pick over everything read and keep the rows that start inside
|
||||
* their range: a workout is canonical, or not, the same way on every surface.
|
||||
*
|
||||
* The reader is async and calls the callback before it first awaits, so in a
|
||||
* `Promise.all` it goes after the plain Prisma calls: an element before it
|
||||
* that threw while the array was being built would leave its rejection
|
||||
* unhandled.
|
||||
*
|
||||
* A read callback may still carry a row cap as a runaway guard. A capped read
|
||||
* that actually hits its cap has lost rows at one end and is outside this
|
||||
* guarantee; the caps sit far above any real account's volume.
|
||||
|
||||
@@ -151,7 +151,11 @@ export async function buildWorkoutsProjection(
|
||||
// round trips. The rows come through the windowed reader: a twin just past
|
||||
// `until`, or a cluster that began just before `since`, decides which row
|
||||
// of the range is canonical exactly as it does for the detail route.
|
||||
const [around, userRow] = await Promise.all([
|
||||
const [userRow, around] = await Promise.all([
|
||||
prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
}),
|
||||
readWorkoutsAroundRange(range, (bounds) =>
|
||||
prisma.workout.findMany({
|
||||
where: {
|
||||
@@ -179,10 +183,6 @@ export async function buildWorkoutsProjection(
|
||||
},
|
||||
}),
|
||||
),
|
||||
prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { sourcePriorityJson: true },
|
||||
}),
|
||||
]);
|
||||
|
||||
const canonical: CanonicalWorkoutRow[] = canonicalWorkoutsInRange(
|
||||
|
||||
Reference in new issue
Block a user