remove everything from the scheduler that's in the repository already

This commit is contained in:
2025-03-27 10:30:12 -07:00
parent ae30660095
commit bba00eb067

View File

@@ -1,16 +1,12 @@
import { ShuttleGetterRepository } from "../../repositories/ShuttleGetterRepository"; import { ShuttleGetterRepository } from "../../repositories/ShuttleGetterRepository";
import { TupleKey } from "../../types/TupleKey";
import { IEta } from "../../entities/entities"; import { IEta } from "../../entities/entities";
import { AppleNotificationSender, NotificationAlertArguments } from "../senders/AppleNotificationSender"; import { AppleNotificationSender, NotificationAlertArguments } from "../senders/AppleNotificationSender";
import { import {
NotificationLookupArguments,
NotificationRepository, NotificationRepository,
ScheduledNotification ScheduledNotification
} from "../../repositories/NotificationRepository"; } from "../../repositories/NotificationRepository";
import { InMemoryNotificationRepository } from "../../repositories/InMemoryNotificationRepository"; import { InMemoryNotificationRepository } from "../../repositories/InMemoryNotificationRepository";
type DeviceIdSecondsThresholdAssociation = { [key: string]: number };
export class ETANotificationScheduler { export class ETANotificationScheduler {
public static readonly defaultSecondsThresholdForNotificationToFire = 180; public static readonly defaultSecondsThresholdForNotificationToFire = 180;
@@ -25,15 +21,6 @@ export class ETANotificationScheduler {
this.sendEtaNotificationImmediatelyIfSecondsRemainingBelowThreshold = this.sendEtaNotificationImmediatelyIfSecondsRemainingBelowThreshold.bind(this); this.sendEtaNotificationImmediatelyIfSecondsRemainingBelowThreshold = this.sendEtaNotificationImmediatelyIfSecondsRemainingBelowThreshold.bind(this);
} }
/**
* An object of device ID arrays to deliver notifications to.
* The key should be a combination of the shuttle ID and
* stop ID, which can be generated using `TupleKey`.
* The value is a dictionary of the device ID to the stored seconds threshold.
* @private
*/
private deviceIdsToDeliverTo: { [key: string]: DeviceIdSecondsThresholdAssociation } = {}
private async sendEtaNotificationImmediately(notificationData: ScheduledNotification): Promise<boolean> { private async sendEtaNotificationImmediately(notificationData: ScheduledNotification): Promise<boolean> {
const { deviceId, shuttleId, stopId } = notificationData; const { deviceId, shuttleId, stopId } = notificationData;
@@ -64,29 +51,25 @@ export class ETANotificationScheduler {
} }
private async etaSubscriberCallback(eta: IEta) { private async etaSubscriberCallback(eta: IEta) {
const tuple = new TupleKey(eta.shuttleId, eta.stopId);
const tupleKey = tuple.toString();
if (this.deviceIdsToDeliverTo[tupleKey] === undefined) {
return;
}
const deviceIdsToRemove = new Set<string>(); const deviceIdsToRemove = new Set<string>();
for (let deviceId of Object.keys(this.deviceIdsToDeliverTo[tupleKey])) { const notifications = await this.notificationRepository.getAllNotificationsForShuttleAndStopId(
const scheduledNotificationData: ScheduledNotification = { eta.shuttleId,
deviceId, eta.stopId
secondsThreshold: this.deviceIdsToDeliverTo[tupleKey][deviceId], )
shuttleId: eta.shuttleId,
stopId: eta.stopId,
}
const deliveredSuccessfully = await this.sendEtaNotificationImmediatelyIfSecondsRemainingBelowThreshold(scheduledNotificationData, eta.secondsRemaining); for (let notification of notifications) {
const deliveredSuccessfully = await this.sendEtaNotificationImmediatelyIfSecondsRemainingBelowThreshold(notification, eta.secondsRemaining);
if (deliveredSuccessfully) { if (deliveredSuccessfully) {
deviceIdsToRemove.add(deviceId); deviceIdsToRemove.add(notification.deviceId);
} }
} }
deviceIdsToRemove.forEach((deviceId) => { deviceIdsToRemove.forEach((deviceId) => {
delete this.deviceIdsToDeliverTo[tupleKey][deviceId] this.notificationRepository.deleteNotificationIfExists({
shuttleId: eta.shuttleId,
stopId: eta.stopId,
deviceId,
})
}); });
} }
@@ -97,83 +80,4 @@ export class ETANotificationScheduler {
return await this.sendEtaNotificationImmediately(notificationObject); return await this.sendEtaNotificationImmediately(notificationObject);
} }
/**
* Queue a notification to be sent.
* @param deviceId The device ID to send the notification to.
* @param shuttleId Shuttle ID of ETA object to check.
* @param stopId Stop ID of ETA object to check.
* @param secondsThreshold Value which specifies the ETA of the shuttle for when
* the notification should fire.
*/
public async scheduleNotification({ deviceId, shuttleId, stopId, secondsThreshold }: ScheduledNotification) {
const tuple = new TupleKey(shuttleId, stopId);
if (this.deviceIdsToDeliverTo[tuple.toString()] === undefined) {
this.deviceIdsToDeliverTo[tuple.toString()] = {};
}
this.deviceIdsToDeliverTo[tuple.toString()][deviceId] = secondsThreshold;
this.shuttleRepository.unsubscribeFromEtaUpdates(this.etaSubscriberCallback);
this.shuttleRepository.subscribeToEtaUpdates(this.etaSubscriberCallback);
}
/**
* Cancel a pending notification.
* @param deviceId The device ID of the notification.
* @param shuttleId Shuttle ID of the ETA object.
* @param stopId Stop ID of the ETA object.
*/
public async cancelNotificationIfExists({ deviceId, shuttleId, stopId }: NotificationLookupArguments) {
const tupleKey = new TupleKey(shuttleId, stopId);
if (
this.deviceIdsToDeliverTo[tupleKey.toString()] === undefined
|| !(deviceId in this.deviceIdsToDeliverTo[tupleKey.toString()])
) {
return;
}
delete this.deviceIdsToDeliverTo[tupleKey.toString()][deviceId];
}
/**
* Check whether the notification is scheduled.
*/
public isNotificationScheduled(lookupArguments: NotificationLookupArguments): boolean {
return this.getSecondsThresholdForScheduledNotification(lookupArguments) != null;
}
public getSecondsThresholdForScheduledNotification({ deviceId, shuttleId, stopId }: NotificationLookupArguments): number | null {
const tuple = new TupleKey(shuttleId, stopId);
if (this.deviceIdsToDeliverTo[tuple.toString()] === undefined) {
return null;
}
return this.deviceIdsToDeliverTo[tuple.toString()][deviceId];
}
/**
* Return all scheduled notification for the given device ID.
* @param deviceId
*/
public async getAllScheduledNotificationsForDevice(deviceId: string): Promise<NotificationLookupArguments[]> {
const scheduledNotifications: ScheduledNotification[] = [];
for (const key of Object.keys(this.deviceIdsToDeliverTo)) {
if (deviceId in this.deviceIdsToDeliverTo[key]) {
const tupleKey = TupleKey.fromExistingStringKey(key);
const shuttleId = tupleKey.tuple[0]
const stopId = tupleKey.tuple[1];
const secondsThreshold = this.deviceIdsToDeliverTo[key][deviceId];
scheduledNotifications.push({
shuttleId,
stopId,
deviceId,
secondsThreshold,
});
}
}
return scheduledNotifications;
}
} }