save the url in redis for 8 hours so rss-feeder will not try to re-save it
This commit is contained in:
@ -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
18
packages/api/src/redis.ts
Normal 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
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -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()
|
||||
|
||||
@ -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}`,
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user