Update InterchangeSystem and caller to construct an ETA repository based on argumetns

This commit is contained in:
2025-11-11 15:16:21 -08:00
parent 57d0171d68
commit 42cd34e755
2 changed files with 59 additions and 10 deletions

View File

@@ -16,6 +16,11 @@ import {
import { RedisParkingRepository } from "../repositories/parking/RedisParkingRepository"; import { RedisParkingRepository } from "../repositories/parking/RedisParkingRepository";
import { RedisShuttleRepository } from "../repositories/shuttle/RedisShuttleRepository"; import { RedisShuttleRepository } from "../repositories/shuttle/RedisShuttleRepository";
import { ShuttleGetterRepository } from "../repositories/shuttle/ShuttleGetterRepository"; import { ShuttleGetterRepository } from "../repositories/shuttle/ShuttleGetterRepository";
import { InMemoryExternalSourceETARepository } from "../repositories/shuttle/eta/InMemoryExternalSourceETARepository";
import { ETAGetterRepository } from "../repositories/shuttle/eta/ETAGetterRepository";
import { RedisSelfUpdatingETARepository } from "../repositories/shuttle/eta/RedisSelfUpdatingETARepository";
import { RedisExternalSourceETARepository } from "../repositories/shuttle/eta/RedisExternalSourceETARepository";
import { InMemorySelfUpdatingETARepository } from "../repositories/shuttle/eta/InMemorySelfUpdatingETARepository";
export interface InterchangeSystemBuilderArguments { export interface InterchangeSystemBuilderArguments {
name: string; name: string;
@@ -34,6 +39,12 @@ export interface InterchangeSystemBuilderArguments {
* ID for the parking repository ID in the codebase. * ID for the parking repository ID in the codebase.
*/ */
parkingSystemId?: string; parkingSystemId?: string;
/**
* Controls whether to self-calculate ETAs or use the external
* shuttle provider for them.
*/
useSelfUpdatingEtas: boolean
} }
export class InterchangeSystem { export class InterchangeSystem {
@@ -42,6 +53,7 @@ export class InterchangeSystem {
public id: string, public id: string,
public shuttleTimedDataLoader: TimedApiBasedRepositoryLoader, public shuttleTimedDataLoader: TimedApiBasedRepositoryLoader,
public shuttleRepository: ShuttleGetterSetterRepository, public shuttleRepository: ShuttleGetterSetterRepository,
public etaRepository: ETAGetterRepository,
public notificationScheduler: ETANotificationScheduler, public notificationScheduler: ETANotificationScheduler,
public notificationRepository: NotificationRepository, public notificationRepository: NotificationRepository,
public parkingTimedDataLoader: TimedApiBasedRepositoryLoader | null, public parkingTimedDataLoader: TimedApiBasedRepositoryLoader | null,
@@ -57,10 +69,14 @@ export class InterchangeSystem {
static async build( static async build(
args: InterchangeSystemBuilderArguments, args: InterchangeSystemBuilderArguments,
) { ) {
const { shuttleRepository, timedShuttleDataLoader } = await InterchangeSystem.buildRedisShuttleLoaderAndRepository(args); const { shuttleRepository, timedShuttleDataLoader, etaRepository } = await InterchangeSystem.buildRedisShuttleLoaderAndRepositories(args);
timedShuttleDataLoader.start(); timedShuttleDataLoader.start();
const { notificationScheduler, notificationRepository } = await InterchangeSystem.buildNotificationSchedulerAndRepository(shuttleRepository, args); const { notificationScheduler, notificationRepository } = await InterchangeSystem.buildNotificationSchedulerAndRepository(
etaRepository,
shuttleRepository,
args
);
notificationScheduler.startListeningForUpdates(); notificationScheduler.startListeningForUpdates();
let { parkingRepository, timedParkingLoader } = await InterchangeSystem.buildRedisParkingLoaderAndRepository(args.parkingSystemId); let { parkingRepository, timedParkingLoader } = await InterchangeSystem.buildRedisParkingLoaderAndRepository(args.parkingSystemId);
@@ -71,6 +87,7 @@ export class InterchangeSystem {
args.id, args.id,
timedShuttleDataLoader, timedShuttleDataLoader,
shuttleRepository, shuttleRepository,
etaRepository,
notificationScheduler, notificationScheduler,
notificationRepository, notificationRepository,
timedParkingLoader, timedParkingLoader,
@@ -78,7 +95,7 @@ export class InterchangeSystem {
); );
} }
private static async buildRedisShuttleLoaderAndRepository(args: InterchangeSystemBuilderArguments) { private static async buildRedisShuttleLoaderAndRepositories(args: InterchangeSystemBuilderArguments) {
const shuttleRepository = new RedisShuttleRepository(); const shuttleRepository = new RedisShuttleRepository();
await shuttleRepository.connect(); await shuttleRepository.connect();
const shuttleDataLoader = new ApiBasedShuttleRepositoryLoader( const shuttleDataLoader = new ApiBasedShuttleRepositoryLoader(
@@ -89,13 +106,26 @@ export class InterchangeSystem {
const timedShuttleDataLoader = new TimedApiBasedRepositoryLoader( const timedShuttleDataLoader = new TimedApiBasedRepositoryLoader(
shuttleDataLoader shuttleDataLoader
); );
return { shuttleRepository, timedShuttleDataLoader };
let etaRepository: ETAGetterRepository;
if (args.useSelfUpdatingEtas) {
etaRepository = new RedisSelfUpdatingETARepository(shuttleRepository);
} else {
etaRepository = new RedisExternalSourceETARepository();
} }
private static async buildNotificationSchedulerAndRepository(shuttleRepository: ShuttleGetterRepository, args: InterchangeSystemBuilderArguments) { return { shuttleRepository, etaRepository, timedShuttleDataLoader };
}
private static async buildNotificationSchedulerAndRepository(
etaRepository: ETAGetterRepository,
shuttleRepository: ShuttleGetterRepository,
args: InterchangeSystemBuilderArguments
) {
const notificationRepository = new RedisNotificationRepository(); const notificationRepository = new RedisNotificationRepository();
await notificationRepository.connect(); await notificationRepository.connect();
const notificationScheduler = new ETANotificationScheduler( const notificationScheduler = new ETANotificationScheduler(
etaRepository,
shuttleRepository, shuttleRepository,
notificationRepository, notificationRepository,
new AppleNotificationSender(), new AppleNotificationSender(),
@@ -138,10 +168,14 @@ export class InterchangeSystem {
static buildForTesting( static buildForTesting(
args: InterchangeSystemBuilderArguments, args: InterchangeSystemBuilderArguments,
) { ) {
const { shuttleRepository, timedShuttleLoader } = InterchangeSystem.buildInMemoryShuttleLoaderAndRepository(args); const { shuttleRepository, timedShuttleLoader, etaRepository } = InterchangeSystem.buildInMemoryShuttleLoaderAndRepositories(args);
// Timed shuttle loader is not started here // Timed shuttle loader is not started here
const { notificationScheduler, notificationRepository } = InterchangeSystem.buildInMemoryNotificationSchedulerAndRepository(shuttleRepository, args); const { notificationScheduler, notificationRepository } = InterchangeSystem.buildInMemoryNotificationSchedulerAndRepository(
etaRepository,
shuttleRepository,
args
);
notificationScheduler.startListeningForUpdates(); notificationScheduler.startListeningForUpdates();
let { parkingRepository, timedParkingLoader } = this.buildInMemoryParkingLoaderAndRepository(args.parkingSystemId); let { parkingRepository, timedParkingLoader } = this.buildInMemoryParkingLoaderAndRepository(args.parkingSystemId);
@@ -152,6 +186,7 @@ export class InterchangeSystem {
args.id, args.id,
timedShuttleLoader, timedShuttleLoader,
shuttleRepository, shuttleRepository,
etaRepository,
notificationScheduler, notificationScheduler,
notificationRepository, notificationRepository,
timedParkingLoader, timedParkingLoader,
@@ -159,9 +194,14 @@ export class InterchangeSystem {
); );
} }
private static buildInMemoryNotificationSchedulerAndRepository(shuttleRepository: UnoptimizedInMemoryShuttleRepository, args: InterchangeSystemBuilderArguments) { private static buildInMemoryNotificationSchedulerAndRepository(
etaRepository: ETAGetterRepository,
shuttleRepository: UnoptimizedInMemoryShuttleRepository,
args: InterchangeSystemBuilderArguments
) {
const notificationRepository = new InMemoryNotificationRepository(); const notificationRepository = new InMemoryNotificationRepository();
const notificationScheduler = new ETANotificationScheduler( const notificationScheduler = new ETANotificationScheduler(
etaRepository,
shuttleRepository, shuttleRepository,
notificationRepository, notificationRepository,
new AppleNotificationSender(false), new AppleNotificationSender(false),
@@ -193,7 +233,7 @@ export class InterchangeSystem {
return { parkingRepository, timedParkingLoader }; return { parkingRepository, timedParkingLoader };
} }
private static buildInMemoryShuttleLoaderAndRepository(args: InterchangeSystemBuilderArguments) { private static buildInMemoryShuttleLoaderAndRepositories(args: InterchangeSystemBuilderArguments) {
const shuttleRepository = new UnoptimizedInMemoryShuttleRepository(); const shuttleRepository = new UnoptimizedInMemoryShuttleRepository();
const shuttleDataLoader = new ApiBasedShuttleRepositoryLoader( const shuttleDataLoader = new ApiBasedShuttleRepositoryLoader(
args.passioSystemId, args.passioSystemId,
@@ -205,7 +245,15 @@ export class InterchangeSystem {
const timedShuttleLoader = new TimedApiBasedRepositoryLoader( const timedShuttleLoader = new TimedApiBasedRepositoryLoader(
shuttleDataLoader shuttleDataLoader
); );
return { shuttleRepository, timedShuttleLoader };
let etaRepository: ETAGetterRepository;
if (args.useSelfUpdatingEtas) {
etaRepository = new InMemorySelfUpdatingETARepository(shuttleRepository);
} else {
etaRepository = new InMemoryExternalSourceETARepository();
}
return { shuttleRepository, etaRepository, timedShuttleLoader };
} }
} }

View File

@@ -23,6 +23,7 @@ const supportedSystems: InterchangeSystemBuilderArguments[] = [
passioSystemId: "263", passioSystemId: "263",
parkingSystemId: ChapmanApiBasedParkingRepositoryLoader.id, parkingSystemId: ChapmanApiBasedParkingRepositoryLoader.id,
name: "Chapman University", name: "Chapman University",
useSelfUpdatingEtas: true,
} }
] ]