From 4f2d61ffe66f2e09ed9322fde28394851e31680b Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Mon, 30 Dec 2024 20:52:22 +0100 Subject: [PATCH] chore(api): Retry on fail --- src/index.ts | 2 +- src/lucida.ts | 17 ++++++++++++----- src/queueManager.ts | 44 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8faf70a..0e56264 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,7 +13,7 @@ app.use(bodyParser.json()); app.get(api + '/queue', (req, res) => { - res.json(qm.getQueue()); + res.json(qm.getQueue().map(qi => qi.album.href)); }); app.post(api + '/queue', (req, res) => { diff --git a/src/lucida.ts b/src/lucida.ts index 8960e9f..fc5928d 100644 --- a/src/lucida.ts +++ b/src/lucida.ts @@ -1,6 +1,6 @@ import {firefox, Page, BrowserContext, Download, Browser, Locator} from 'playwright'; -export async function lucida(album: URL, baseTimeout: number, context: BrowserContext): Promise { +export async function lucida(album: URL, baseTimeout: number, context: BrowserContext): Promise { const page: Page = await context.newPage(); await page.goto('/'); @@ -28,14 +28,21 @@ export async function lucida(album: URL, baseTimeout: number, context: BrowserCo // Start download await page.getByText('download full album').click(); - // Save the download to the Downloads folder - const download: Download = await page.waitForEvent('download', { timeout: baseTimeout * trackCount }); - // TODO Set path (configurable) - await download.saveAs('/home/tdpeuter/Downloads/lucida/' + download.suggestedFilename()); + try { + // Save the download to the Downloads folder + const download: Download = await page.waitForEvent('download', { timeout: baseTimeout * trackCount }); + // TODO Set path (configurable) + await download.saveAs('/home/tdpeuter/Downloads/lucida/' + download.suggestedFilename()); + } catch { + await page.close(); + return 'Download timed out'; + } // TODO Check if booklet is available. await page.close(); + + return true; } async function booklet(album: URL, context: BrowserContext): Promise { diff --git a/src/queueManager.ts b/src/queueManager.ts index a180b31..467e7ef 100644 --- a/src/queueManager.ts +++ b/src/queueManager.ts @@ -1,16 +1,25 @@ import {firefox, Browser, BrowserContext, Page} from "playwright"; import {lucida} from "./lucida"; +type QueueItem = { + album: URL, + timeout: number, + retries?: number +} + +const DEFAULT_TIMEOUT: number = 60000; +const MAX_RETRIES: number = 3; + class QueueManager { private browser: Browser | null; - private queue: URL[]; + private queue: QueueItem[]; constructor() { this.browser = null; this.queue = []; } - getQueue(): URL[] { + getQueue(): QueueItem[] { return this.queue; } @@ -18,13 +27,17 @@ class QueueManager { // Check if the URL is a valid URL try { const url: URL = new URL(link); + const qi: QueueItem = { + album: url, + timeout: DEFAULT_TIMEOUT + }; // Check if the URL was already added to the queue - if (this.queue.includes(url)) { + if (this.queue.some(q => q.album.href === qi.album.href)) { return "Album already in queue"; } - this.queue.push(url); + this.queue.push(qi); this.processQueue(); return true; } catch { @@ -66,15 +79,28 @@ class QueueManager { }); while (this.queue.length > 0) { - const album: URL | undefined = this.queue.shift(); - if (album === undefined) { + const qi: QueueItem | undefined = this.queue.shift(); + if (qi === undefined) { continue; } - // TODO + const album: URL = qi.album; console.log(`Processing ${album.href}`); - await lucida(album, 60000, context); - console.log(`Finished processing ${album.href}`); + const result: boolean | string = await lucida(album, qi.timeout, context); + if (result === true) { + console.log(`Finished processing ${album.href}`); + } else { + if (qi.retries === undefined) { + qi.retries = 0; + } + qi.retries++; + qi.timeout *= 2; + if (qi.retries < MAX_RETRIES) { + this.queue.push(qi); + } else { + console.error(`Failed to process ${album.href} after 3 retries: ${result}`); + } + } } console.log('Shutting down browser');