Changing daily reservations to have 2 attempts and then finally go to waitlist

This commit is contained in:
Collin Duncan 2024-02-23 07:35:35 -06:00
parent 09f05d6758
commit 533080b0ad
No known key found for this signature in database
GPG key ID: 9584E0870D990D97
4 changed files with 39 additions and 32 deletions

View file

@ -8,6 +8,8 @@ import { NtfyProvider } from '../ntfy/provider'
import { RESERVATIONS_QUEUE_NAME } from './config' import { RESERVATIONS_QUEUE_NAME } from './config'
import { ReservationsService } from './service' import { ReservationsService } from './service'
export const DAILY_RESERVATIONS_ATTEMPTS = 2
@Injectable() @Injectable()
export class ReservationsCronService { export class ReservationsCronService {
constructor( constructor(
@ -36,7 +38,10 @@ export class ReservationsCronService {
`Found ${reservationsToPerform.length} reservations to perform`, `Found ${reservationsToPerform.length} reservations to perform`,
) )
await this.reservationsQueue.addBulk( await this.reservationsQueue.addBulk(
reservationsToPerform.map((r) => ({ data: r, opts: { attempts: 1 } })), reservationsToPerform.map((r) => ({
data: r,
opts: { attempts: DAILY_RESERVATIONS_ATTEMPTS },
})),
) )
this.loggerService.log('handleDailyReservations ending') this.loggerService.log('handleDailyReservations ending')
await this.ntfyProvider.sendCronStopNotification( await this.ntfyProvider.sendCronStopNotification(

View file

@ -12,6 +12,7 @@ import {
import { RESERVATIONS_QUEUE_NAME } from './config' import { RESERVATIONS_QUEUE_NAME } from './config'
import { Reservation } from './entity' import { Reservation } from './entity'
import { ReservationsService } from './service' import { ReservationsService } from './service'
import { DAILY_RESERVATIONS_ATTEMPTS } from './cron'
@Processor(RESERVATIONS_QUEUE_NAME) @Processor(RESERVATIONS_QUEUE_NAME)
export class ReservationsWorker { export class ReservationsWorker {
@ -42,45 +43,42 @@ export class ReservationsWorker {
reservation.dateRangeStart, reservation.dateRangeStart,
reservation.dateRangeEnd, reservation.dateRangeEnd,
) )
await this.performReservation(reservation) await this.performReservation(reservation, job.attemptsMade)
} }
private async handleReservationErrors( private async handleReservationErrors(
error: Error, error: Error,
reservation: Reservation, reservation: Reservation,
attemptsMade: number,
) { ) {
switch (true) { if (error instanceof NoCourtAvailableError) {
case error instanceof NoCourtAvailableError: { this.loggerService.warn('No court available')
this.loggerService.warn('No court available') }
if (!reservation.waitListed) { this.loggerService.error('Error while performing reservation', error)
this.loggerService.log('Adding reservation to waiting list') if (
await this.ntfyProvider.sendReservationWaitlistedNotification( attemptsMade === DAILY_RESERVATIONS_ATTEMPTS &&
reservation.id, !reservation.waitListed
reservation.dateRangeStart, ) {
reservation.dateRangeEnd, this.loggerService.log('Adding reservation to waiting list')
) await this.ntfyProvider.sendReservationWaitlistedNotification(
await this.addReservationToWaitList(reservation) reservation.id,
} reservation.dateRangeStart,
return reservation.dateRangeEnd,
} )
default: await this.brService.addReservationToWaitList(reservation)
this.loggerService.error('Error while performing reservation', error)
await this.ntfyProvider.sendErrorPerformingReservationNotification(
reservation.id,
reservation.dateRangeStart,
reservation.dateRangeEnd,
error,
)
throw error
} }
} }
async performReservation(reservation: Reservation) { async performReservation(reservation: Reservation, attemptsMade: number) {
try { try {
await this.brService.performReservation(reservation) await this.brService.performReservation(reservation)
await this.reservationsService.deleteById(reservation.id) await this.reservationsService.deleteById(reservation.id)
} catch (error: unknown) { } catch (error: unknown) {
await this.handleReservationErrors(error as Error, reservation) await this.handleReservationErrors(
error as Error,
reservation,
attemptsMade,
)
} }
} }

View file

@ -83,10 +83,14 @@ export class BaanReserverenService {
} }
private async handleError() { private async handleError() {
await this.page.screenshot({ await this.page
type: 'png', .screenshot({
path: path.resolve('.', `${Date.now()}_error-screenshot.png`), type: 'png',
}).catch((reason: any) => this.loggerService.warn('Failed to take screenshot', { reason })) path: path.resolve('.', `${Date.now()}_error-screenshot.png`),
})
.catch((reason: any) =>
this.loggerService.warn('Failed to take screenshot', { reason }),
)
} }
private async checkSession(username: string) { private async checkSession(username: string) {

View file

@ -10,7 +10,7 @@ export const EmptyPageFactory: FactoryProvider<Page> = {
useFactory: async (runnerService: RunnerService) => { useFactory: async (runnerService: RunnerService) => {
const browser = await runnerService.getBrowser() const browser = await runnerService.getBrowser()
const page = await browser.newPage() const page = await browser.newPage()
// Default navigation timeout and loading timeout of 5s // Default navigation timeout and loading timeout of 5s
page.setDefaultNavigationTimeout(5_000) page.setDefaultNavigationTimeout(5_000)
page.setDefaultTimeout(5_000) page.setDefaultTimeout(5_000)