Swap implementations of two handler methods, and add reference implementation for adding travel time data

This commit is contained in:
2025-11-11 19:51:31 -08:00
parent 88a393c1ad
commit ac81806b26

View File

@@ -77,31 +77,20 @@ export class RedisSelfUpdatingETARepository extends BaseRedisETARepository imple
this.shuttleRepository.removeListener(ShuttleRepositoryEvent.SHUTTLE_WILL_ARRIVE_AT_STOP, this.handleShuttleWillArriveAtStop);
}
private handleShuttleUpdate(shuttle: IShuttle) {
// TODO: handle shuttle update
}
private async handleShuttleUpdate(shuttle: IShuttle) {
const lastStop = await this.shuttleRepository.getShuttleLastStopArrival(shuttle.id);
if (!lastStop) return;
private async handleShuttleWillArriveAtStop(
shuttleArrival: ShuttleStopArrival,
) {
const lastStop = await this.shuttleRepository.getShuttleLastStopArrival(shuttleArrival.shuttleId);
if (lastStop == undefined) return;
const shuttle = await this.shuttleRepository.getShuttleById(shuttleArrival.shuttleId);
if (shuttle == null) return;
const lastOrderedStop = await this.shuttleRepository.getOrderedStopByRouteAndStopId(shuttle.routeId, lastStop.stopId);
const nextStop = lastOrderedStop?.nextStop;
if (!nextStop) return;
let referenceCurrentTime = new Date();
if (this.referenceTime != null) {
referenceCurrentTime = this.referenceTime;
}
const oneWeekAgo = new Date(referenceCurrentTime.getTime() - (60 * 60 * 24 * 7 * 1000));
const lastOrderedStop = await this.shuttleRepository.getOrderedStopByRouteAndStopId(shuttle.routeId, lastStop.stopId);
const nextStop = lastOrderedStop?.nextStop;
if (nextStop == null) return;
const travelTimeSeconds = await this.getAverageTravelTimeSeconds({
routeId: shuttle.routeId,
fromStopId: lastStop.stopId,
@@ -115,6 +104,7 @@ export class RedisSelfUpdatingETARepository extends BaseRedisETARepository imple
const elapsedTimeMs = referenceCurrentTime.getTime() - lastStop.timestamp.getTime();
const predictedTimeSeconds = travelTimeSeconds - (elapsedTimeMs / 1000);
// TODO: update multiple ETAs
await this.addOrUpdateEta({
secondsRemaining: predictedTimeSeconds,
shuttleId: shuttle.id,
@@ -123,4 +113,94 @@ export class RedisSelfUpdatingETARepository extends BaseRedisETARepository imple
updatedTime: new Date(),
});
}
private async handleShuttleWillArriveAtStop(
shuttleArrival: ShuttleStopArrival,
) {
const lastStopTimestamp = await this.shuttleRepository.getShuttleLastStopArrival(shuttleArrival.shuttleId);
if (lastStopTimestamp) {
const shuttle = await this.shuttleRepository.getShuttleById(lastStopTimestamp.shuttleId);
if (!shuttle) return;
const routeId = shuttle.routeId;
const fromStopId = lastStopTimestamp.stopId;
const toStopId = shuttleArrival.stopId;
const travelTimeSeconds = (shuttleArrival.timestamp.getTime() - lastStopTimestamp.timestamp.getTime()) / 1000;
await this.addTravelTimeDataPoint({ routeId, fromStopId, toStopId, }, travelTimeSeconds, shuttleArrival.timestamp.getTime());
}
}
public async addTravelTimeDataPoint(
{ routeId, fromStopId, toStopId }: ShuttleTravelTimeDataIdentifier,
travelTimeSeconds: number,
timestamp = Date.now(),
): Promise<void> {
const historicalEtaTimeSeriesKey = this.createHistoricalEtaTimeSeriesKey(routeId, fromStopId, toStopId);
try {
await this.redisClient.sendCommand([
'TS.ADD',
historicalEtaTimeSeriesKey,
timestamp.toString(),
travelTimeSeconds.toString(),
'LABELS',
'routeId',
routeId,
'fromStopId',
fromStopId,
'toStopId',
toStopId
]);
} catch (error) {
await this.createHistoricalEtaTimeSeriesAndAddDataPoint(
historicalEtaTimeSeriesKey,
timestamp,
travelTimeSeconds,
routeId,
fromStopId,
toStopId
);
}
}
private async createHistoricalEtaTimeSeriesAndAddDataPoint(
timeSeriesKey: string,
timestamp: number,
travelTimeSeconds: number,
routeId: string,
fromStopId: string,
toStopId: string,
): Promise<void> {
try {
await this.redisClient.sendCommand([
'TS.CREATE',
timeSeriesKey,
'RETENTION',
'2678400000', // one month in milliseconds
'LABELS',
'routeId',
routeId,
'fromStopId',
fromStopId,
'toStopId',
toStopId
]);
await this.redisClient.sendCommand([
'TS.ADD',
timeSeriesKey,
timestamp.toString(),
travelTimeSeconds.toString()
]);
} catch (createError) {
await this.redisClient.sendCommand([
'TS.ADD',
timeSeriesKey,
timestamp.toString(),
travelTimeSeconds.toString()
]);
}
}
}