From 397eb2b588d05cb4c5b8ab1c3ac67adcc400c3d6 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Fri, 14 Nov 2025 10:34:48 -0800 Subject: [PATCH 1/3] Change one-hour windows to two hours A set of shuttles may only make a complete set of trips in two hours, so this should capture more data when calculating ETAs. --- .../shuttle/eta/RedisSelfUpdatingETARepository.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts b/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts index 60e07b4..4f61368 100644 --- a/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts +++ b/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts @@ -133,6 +133,7 @@ export class RedisSelfUpdatingETARepository extends BaseRedisETARepository imple const oneDayAgo = new Date(referenceCurrentTime.getTime() - (60 * 60 * 24 * 1000)); const twoHoursAgo = new Date(referenceCurrentTime.getTime() - (120 * 60 * 1000)); + const twoHoursMs = 120 * 60 * 1000; const travelTimeSeconds = await this.getAverageTravelTimeSecondsWithFallbacks({ routeId: shuttle.routeId, fromStopId: currentStop.stopId, @@ -140,11 +141,11 @@ export class RedisSelfUpdatingETARepository extends BaseRedisETARepository imple }, [ { from: oneWeekAgo, - to: new Date(oneWeekAgo.getTime() + (60 * 60 * 1000)) + to: new Date(oneWeekAgo.getTime() + (twoHoursMs)) }, { from: oneDayAgo, - to: new Date(oneDayAgo.getTime() + (60 * 60 * 1000)) + to: new Date(oneDayAgo.getTime() + (twoHoursMs)) }, { from: twoHoursAgo, From f8e7670b3f38313c9ad40ddf16603ba6128627fc Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Fri, 14 Nov 2025 10:40:37 -0800 Subject: [PATCH 2/3] For data from last week and previous day, look back instead of looking forward --- .../eta/InMemorySelfUpdatingETARepository.ts | 13 +++++++------ .../shuttle/eta/RedisSelfUpdatingETARepository.ts | 10 +++++----- .../SelfUpdatingETARepositorySharedTests.test.ts | 10 +++++----- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/repositories/shuttle/eta/InMemorySelfUpdatingETARepository.ts b/src/repositories/shuttle/eta/InMemorySelfUpdatingETARepository.ts index 917e6bc..868178f 100644 --- a/src/repositories/shuttle/eta/InMemorySelfUpdatingETARepository.ts +++ b/src/repositories/shuttle/eta/InMemorySelfUpdatingETARepository.ts @@ -110,23 +110,24 @@ export class InMemorySelfUpdatingETARepository extends BaseInMemoryETARepository const oneWeekAgo = new Date(referenceCurrentTime.getTime() - (60 * 60 * 24 * 7 * 1000)); const oneDayAgo = new Date(referenceCurrentTime.getTime() - (60 * 60 * 24 * 1000)); - const oneHourAgo = new Date(referenceCurrentTime.getTime() - (60 * 60 * 1000)); + const twoHoursAgo = new Date(referenceCurrentTime.getTime() - (60 * 60 * 1000)); + const twoHoursInMs = 120 * 60 * 1000; const travelTimeSeconds = await this.getAverageTravelTimeSecondsWithFallbacks({ routeId: shuttle.routeId, fromStopId: currentStop.stopId, toStopId: nextStop.stopId, }, [ { - from: oneWeekAgo, - to: new Date(oneWeekAgo.getTime() + (60 * 60 * 1000)) + from: new Date(oneWeekAgo.getTime() - (twoHoursInMs)), + to: oneWeekAgo, }, { - from: oneDayAgo, - to: new Date(oneDayAgo.getTime() + (60 * 60 * 1000)) + from: new Date(oneDayAgo.getTime() - (twoHoursInMs)), + to: oneDayAgo, }, { - from: oneHourAgo, + from: twoHoursAgo, to: new Date(), } ]); diff --git a/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts b/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts index 4f61368..0514ec2 100644 --- a/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts +++ b/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts @@ -133,19 +133,19 @@ export class RedisSelfUpdatingETARepository extends BaseRedisETARepository imple const oneDayAgo = new Date(referenceCurrentTime.getTime() - (60 * 60 * 24 * 1000)); const twoHoursAgo = new Date(referenceCurrentTime.getTime() - (120 * 60 * 1000)); - const twoHoursMs = 120 * 60 * 1000; + const twoHoursInMs = 120 * 60 * 1000; const travelTimeSeconds = await this.getAverageTravelTimeSecondsWithFallbacks({ routeId: shuttle.routeId, fromStopId: currentStop.stopId, toStopId: nextStop.stopId, }, [ { - from: oneWeekAgo, - to: new Date(oneWeekAgo.getTime() + (twoHoursMs)) + from: new Date(oneWeekAgo.getTime() - (twoHoursInMs)), + to: oneWeekAgo, }, { - from: oneDayAgo, - to: new Date(oneDayAgo.getTime() + (twoHoursMs)) + from: new Date(oneDayAgo.getTime() - (twoHoursInMs)), + to: oneDayAgo, }, { from: twoHoursAgo, diff --git a/src/repositories/shuttle/eta/__tests__/SelfUpdatingETARepositorySharedTests.test.ts b/src/repositories/shuttle/eta/__tests__/SelfUpdatingETARepositorySharedTests.test.ts index f490b0f..b260e3e 100644 --- a/src/repositories/shuttle/eta/__tests__/SelfUpdatingETARepositorySharedTests.test.ts +++ b/src/repositories/shuttle/eta/__tests__/SelfUpdatingETARepositorySharedTests.test.ts @@ -121,9 +121,9 @@ describe.each(repositoryImplementations)('$name', (holder) => { const { route, systemId, stop1, stop2, stop3 } = await setupRouteAndOrderedStops(); // Populating travel time data - const firstStopArrivalTime = new Date(2025, 0, 1, 12, 0, 0); - const secondStopArrivalTime = new Date(2025, 0, 1, 12, 15, 0); - const thirdStopArrivalTime = new Date(2025, 0, 1, 12, 20, 0); + const firstStopArrivalTime = new Date(2025, 0, 1, 11, 0, 0); + const secondStopArrivalTime = new Date(2025, 0, 1, 11, 15, 0); + const thirdStopArrivalTime = new Date(2025, 0, 1, 11, 20, 0); repository.setReferenceTime(currentTime); repository.startListeningForUpdates(); @@ -185,8 +185,8 @@ describe.each(repositoryImplementations)('$name', (holder) => { ); }, 60000); - test("uses previous hour fallback calculation when no data available from one day ago", async () => { - const shuttleSecondArrivalTimeAtFirstStop = new Date(2025, 0, 1, 13, 5, 0); + test("uses previous two-hour fallback calculation when no data available from one day ago", async () => { + const shuttleSecondArrivalTimeAtFirstStop = new Date(2025, 0, 1, 12, 5, 0); const currentTime = new Date(shuttleSecondArrivalTimeAtFirstStop.getTime() + 7 * 60 * 1000); await assertEtaIsValidGivenCurrentTimeAndSecondArrivalTime( currentTime, shuttleSecondArrivalTimeAtFirstStop From 8621f10721cf9845a28162ce367af95ed70d2f83 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Fri, 14 Nov 2025 10:49:23 -0800 Subject: [PATCH 3/3] Switch the order of fallbacks (previous 2h first) Data from the current day is more representative of current traffic conditions than the same data from a previous day. --- .../shuttle/eta/InMemorySelfUpdatingETARepository.ts | 10 +++++----- .../shuttle/eta/RedisSelfUpdatingETARepository.ts | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/repositories/shuttle/eta/InMemorySelfUpdatingETARepository.ts b/src/repositories/shuttle/eta/InMemorySelfUpdatingETARepository.ts index 868178f..89212ab 100644 --- a/src/repositories/shuttle/eta/InMemorySelfUpdatingETARepository.ts +++ b/src/repositories/shuttle/eta/InMemorySelfUpdatingETARepository.ts @@ -119,17 +119,17 @@ export class InMemorySelfUpdatingETARepository extends BaseInMemoryETARepository toStopId: nextStop.stopId, }, [ { - from: new Date(oneWeekAgo.getTime() - (twoHoursInMs)), - to: oneWeekAgo, + from: twoHoursAgo, + to: new Date(), }, { from: new Date(oneDayAgo.getTime() - (twoHoursInMs)), to: oneDayAgo, }, { - from: twoHoursAgo, - to: new Date(), - } + from: new Date(oneWeekAgo.getTime() - (twoHoursInMs)), + to: oneWeekAgo, + }, ]); if (travelTimeSeconds == undefined) return; diff --git a/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts b/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts index 0514ec2..76e723b 100644 --- a/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts +++ b/src/repositories/shuttle/eta/RedisSelfUpdatingETARepository.ts @@ -140,17 +140,17 @@ export class RedisSelfUpdatingETARepository extends BaseRedisETARepository imple toStopId: nextStop.stopId, }, [ { - from: new Date(oneWeekAgo.getTime() - (twoHoursInMs)), - to: oneWeekAgo, + from: twoHoursAgo, + to: new Date(), }, { from: new Date(oneDayAgo.getTime() - (twoHoursInMs)), to: oneDayAgo, }, { - from: twoHoursAgo, - to: new Date(), - } + from: new Date(oneWeekAgo.getTime() - (twoHoursInMs)), + to: oneWeekAgo, + }, ]); if (travelTimeSeconds == undefined) return;