save the url in redis for 8 hours so rss-feeder will not try to re-save it

This commit is contained in:
Hongbo Wu
2024-01-04 18:03:34 +08:00
parent 0f774b6ae4
commit 08c4624fce
6 changed files with 43 additions and 1 deletions

View File

@ -82,6 +82,7 @@
"pg": "^8.3.3",
"postgrator": "^4.2.0",
"private-ip": "^2.3.3",
"redis": "^4.3.1",
"rss-parser": "^3.13.0",
"sanitize-html": "^2.3.2",
"sax": "^1.3.0",

18
packages/api/src/redis.ts Normal file
View File

@ -0,0 +1,18 @@
import { createClient } from 'redis'
import { env } from './env'
export const redisClient = createClient({
url: env.redis.url,
socket: {
tls: env.redis.url?.startsWith('rediss://'), // rediss:// is the protocol for TLS
cert: env.redis.cert?.replace(/\\n/g, '\n'), // replace \n with new line
rejectUnauthorized: false, // for self-signed certs
connectTimeout: 10000, // 10 seconds
reconnectStrategy(retries: number): number | Error {
if (retries > 10) {
return new Error('Retries exhausted')
}
return 1000
},
},
})

View File

@ -15,6 +15,7 @@ import { config, loggers } from 'winston'
import { makeApolloServer } from './apollo'
import { appDataSource } from './data_source'
import { env } from './env'
import { redisClient } from './redis'
import { articleRouter } from './routers/article_router'
import { authRouter } from './routers/auth/auth_router'
import { mobileAuthRouter } from './routers/auth/mobile/mobile_auth_router'
@ -157,6 +158,8 @@ const main = async (): Promise<void> => {
// as healthy.
await appDataSource.initialize()
await redisClient.connect()
const { app, apollo, httpServer } = createApp()
await apollo.start()

View File

@ -13,6 +13,7 @@ import {
SavePageInput,
SaveResult,
} from '../generated/graphql'
import { redisClient } from '../redis'
import { authTrx } from '../repository'
import { enqueueThumbnailTask } from '../utils/createTask'
import {
@ -194,6 +195,14 @@ export const savePage = async (
}
}
// save the url in redis for 8 hours so rss-feeder won't try to re-save it
const redisKey = `recent-saved-item:${user.id}:${itemToSave.originalUrl}`
const expireInSeconds = 60 * 60 * 8
await redisClient.set(redisKey, 1, {
EX: expireInSeconds,
NX: true,
})
return {
clientRequestId,
url: `${homePageURL()}/${user.profile.username}/${slug}`,

View File

@ -109,6 +109,10 @@ interface BackendEnv {
max: number
}
}
redis: {
url?: string
cert?: string
}
}
/***
@ -173,6 +177,8 @@ const nullableEnvVars = [
'INTEGRATION_EXPORTER_URL',
'INTEGRATION_IMPORTER_URL',
'SUBSCRIPTION_FEED_MAX',
'REDIS_URL',
'REDIS_CERT',
] // Allow some vars to be null/empty
/* If not in GAE and Prod/QA/Demo env (f.e. on localhost/dev env), allow following env vars to be null */
@ -316,6 +322,10 @@ export function getEnv(): BackendEnv {
: 256, // default to 256
},
}
const redis = {
url: parse('REDIS_URL'),
cert: parse('REDIS_CERT'),
}
return {
pg,
@ -338,6 +348,7 @@ export function getEnv(): BackendEnv {
gcp,
pocket,
subscription,
redis,
}
}

View File

@ -224,7 +224,7 @@ const isItemRecentlySaved = async (
userId: string,
url: string
) => {
const key = `rss-recent-save:${userId}:${url}`
const key = `recent-saved-item:${userId}:${url}`
const result = await redisClient.get(key)
return !!result
}