From 1c7ca35d8539daaff3c00c957ecc7018a367347d Mon Sep 17 00:00:00 2001 From: Ayo Date: Thu, 7 Aug 2025 17:31:15 +0200 Subject: [PATCH] feat: use Redis as simple cache for fetched articles --- .vscode/settings.json | 1 + package.json | 1 + pnpm-lock.yaml | 69 +++++++++++++++++++++++++++++++++++++++++++ src/pages/index.astro | 30 +++++++++++++++---- 4 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{} diff --git a/package.json b/package.json index ac29cd4..b18b170 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "astro": "^5.12.8", "astro-iconify": "^1.2.0", "fastify": "^5.4.0", + "redis": "^5.8.0", "ultrahtml": "^1.6.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2708548..eee127b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: fastify: specifier: ^5.4.0 version: 5.4.0 + redis: + specifier: ^5.8.0 + version: 5.8.0 ultrahtml: specifier: ^1.6.0 version: 1.6.0 @@ -855,6 +858,34 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@redis/bloom@5.8.0': + resolution: {integrity: sha512-kpKZzAAjGiGYn88Bqq6+ozxPg6kGYWRZH9vnOwGcoSCbrW14SZpZVMYMFSio8FH9ZJUdUcmT/RLGlA1W1t0UWQ==} + engines: {node: '>= 18'} + peerDependencies: + '@redis/client': ^5.8.0 + + '@redis/client@5.8.0': + resolution: {integrity: sha512-ywZjKGoSSAECGYOd9bJpws6d4867SN686obUWT/sRmo1c/Q8V+jWyInvlqwKa0BOvTHHwYeB2WFUEvd6PADeOQ==} + engines: {node: '>= 18'} + + '@redis/json@5.8.0': + resolution: {integrity: sha512-xPBpwY6aKoRzMSu67MpwrBiSliON9bfHo9Y/pSPBjW8/KoOm1MzGqwJUO20qdjXpFoKJsDWwxIE1LHdBNzcImw==} + engines: {node: '>= 18'} + peerDependencies: + '@redis/client': ^5.8.0 + + '@redis/search@5.8.0': + resolution: {integrity: sha512-lF9pNv9vySmirm1EzCH6YeRjhvH6lLT7tvebYHEM7WTkEQ/7kZWb4athliKESHpxzTQ36U9UbzuedSywHV6OhQ==} + engines: {node: '>= 18'} + peerDependencies: + '@redis/client': ^5.8.0 + + '@redis/time-series@5.8.0': + resolution: {integrity: sha512-kPTlW2ACXokjQNXjCD8Pw9mHDoB94AHUlHFahyjxz9lUJUVwiva2Dgfrd2k3JxHhSBqyY2PREIj9YwIUSTSSqQ==} + engines: {node: '>= 18'} + peerDependencies: + '@redis/client': ^5.8.0 + '@rollup/pluginutils@5.2.0': resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} engines: {node: '>=14.0.0'} @@ -1431,6 +1462,10 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -2972,6 +3007,10 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} + redis@5.8.0: + resolution: {integrity: sha512-re0MHm1KHbiVIUPDGoUM3jldvjH5EM/wGZ3A33gyUYoC/UnVNKNnZHM5hcJVry7L2O2eJU3nflSXTliv10BTKg==} + engines: {node: '>= 18'} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -4592,6 +4631,26 @@ snapshots: '@pkgr/core@0.2.9': {} + '@redis/bloom@5.8.0(@redis/client@5.8.0)': + dependencies: + '@redis/client': 5.8.0 + + '@redis/client@5.8.0': + dependencies: + cluster-key-slot: 1.1.2 + + '@redis/json@5.8.0(@redis/client@5.8.0)': + dependencies: + '@redis/client': 5.8.0 + + '@redis/search@5.8.0(@redis/client@5.8.0)': + dependencies: + '@redis/client': 5.8.0 + + '@redis/time-series@5.8.0(@redis/client@5.8.0)': + dependencies: + '@redis/client': 5.8.0 + '@rollup/pluginutils@5.2.0(rollup@4.46.2)': dependencies: '@types/estree': 1.0.8 @@ -5343,6 +5402,8 @@ snapshots: clsx@2.1.1: {} + cluster-key-slot@1.1.2: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -7243,6 +7304,14 @@ snapshots: real-require@0.2.0: {} + redis@5.8.0: + dependencies: + '@redis/bloom': 5.8.0(@redis/client@5.8.0) + '@redis/client': 5.8.0 + '@redis/json': 5.8.0(@redis/client@5.8.0) + '@redis/search': 5.8.0(@redis/client@5.8.0) + '@redis/time-series': 5.8.0(@redis/client@5.8.0) + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 diff --git a/src/pages/index.astro b/src/pages/index.astro index bf695a1..9696b13 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,11 +1,16 @@ --- -import { ArticleData, extract } from '@extractus/article-extractor' +import { createClient } from 'redis' +import { type ArticleData, extract } from '@extractus/article-extractor' import SimpleAddressBar from '../components/SimpleAddressBar.astro' import Post from '../components/Post.astro' import App from '../layouts/App.astro' import Library from '../components/Library.astro' import Footer from '../components/Footer.astro' +const client = createClient() +// TODO: put on a log file +client.on('error', (err) => console.error('Redis Client Error', err)) +await client.connect() export const prerender = false let url = Astro.url.searchParams.get('url') @@ -15,12 +20,25 @@ while (url?.startsWith(Astro.url.origin)) { url = new URL(url).searchParams.get('url') } -if (url) - try { - article = await extract(url) - } catch { - article = null +if (url) { + // try cache + article = (await client.json.get(url)) as ArticleData + if (article !== null) { + console.log('>>> Using cached content', article.url) + } else { + try { + article = await extract(url) + console.log('>>> Using fetched content', article?.url) + if (article !== null) { + // cache via redis + await client.json.set(url, '$', article) + console.log('>>> Added to cache', article.url) + } + } catch { + article = null + } } +} ---