feat: allow empty and async lock for AI apis
This commit is contained in:
parent
a3071a65a7
commit
3574736ae3
|
|
@ -1,8 +1,12 @@
|
|||
import AsyncLock from "async-lock"
|
||||
|
||||
import { toGateway } from "~/lib/ipfs-parser"
|
||||
import prisma from "~/lib/prisma.server"
|
||||
import { cacheGet } from "~/lib/redis.server"
|
||||
import { NextServerResponse, getQuery } from "~/lib/server-helper"
|
||||
|
||||
const lock = new AsyncLock()
|
||||
|
||||
const getOriginalScore = async (cid: string) => {
|
||||
try {
|
||||
let { content } = await (await fetch(toGateway(`ipfs://${cid}`))).json()
|
||||
|
|
@ -63,50 +67,55 @@ const getOriginalScore = async (cid: string) => {
|
|||
async function getScore(cid: string) {
|
||||
const score = await cacheGet({
|
||||
key: ["summary_score", cid],
|
||||
allowEmpty: true,
|
||||
noUpdate: true,
|
||||
getValueFun: async () => {
|
||||
const meta = await prisma.metadata.findFirst({
|
||||
where: {
|
||||
uri: `ipfs://${cid}`,
|
||||
},
|
||||
})
|
||||
if (meta) {
|
||||
if (meta?.ai_score !== null) {
|
||||
return {
|
||||
number: meta.ai_score,
|
||||
reason: meta.ai_score_reason,
|
||||
let resut
|
||||
await lock.acquire(cid, async () => {
|
||||
const meta = await prisma.metadata.findFirst({
|
||||
where: {
|
||||
uri: `ipfs://${cid}`,
|
||||
},
|
||||
})
|
||||
if (meta) {
|
||||
if (meta?.ai_score !== null) {
|
||||
resut = {
|
||||
number: meta.ai_score,
|
||||
reason: meta.ai_score_reason,
|
||||
}
|
||||
} else {
|
||||
const score = await getOriginalScore(cid)
|
||||
if (score) {
|
||||
await prisma.metadata.update({
|
||||
where: {
|
||||
uri: `ipfs://${cid}`,
|
||||
},
|
||||
data: {
|
||||
ai_score: score.number,
|
||||
ai_score_reason: score.reason,
|
||||
},
|
||||
})
|
||||
|
||||
resut = score
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const score = await getOriginalScore(cid)
|
||||
if (score) {
|
||||
await prisma.metadata.update({
|
||||
where: {
|
||||
uri: `ipfs://${cid}`,
|
||||
},
|
||||
await prisma.metadata.create({
|
||||
data: {
|
||||
uri: `ipfs://${cid}`,
|
||||
ai_score: score.number,
|
||||
ai_score_reason: score.reason,
|
||||
},
|
||||
})
|
||||
|
||||
return score
|
||||
resut = score
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const score = await getOriginalScore(cid)
|
||||
if (score) {
|
||||
await prisma.metadata.create({
|
||||
data: {
|
||||
uri: `ipfs://${cid}`,
|
||||
ai_score: score.number,
|
||||
ai_score_reason: score.reason,
|
||||
},
|
||||
})
|
||||
|
||||
return score
|
||||
}
|
||||
}
|
||||
})
|
||||
return resut
|
||||
},
|
||||
noUpdate: true,
|
||||
})
|
||||
|
||||
return score
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export async function cacheGet(options: {
|
|||
key: string | (Record<string, any> | string | undefined | number)[]
|
||||
getValueFun: () => Promise<any>
|
||||
noUpdate?: boolean
|
||||
allowEmpty?: boolean
|
||||
}) {
|
||||
const redis = await redisPromise
|
||||
if (redis && redis.status === "ready") {
|
||||
|
|
@ -57,17 +58,32 @@ export async function cacheGet(options: {
|
|||
}
|
||||
return JSON.parse(cacheValue)
|
||||
} else {
|
||||
const value = await options.getValueFun()
|
||||
if (options.noUpdate) {
|
||||
await redis.set(redisKey, JSON.stringify(value))
|
||||
if (options.allowEmpty) {
|
||||
options.getValueFun().then(async (value) => {
|
||||
if (options.noUpdate) {
|
||||
await redis.set(redisKey, JSON.stringify(value))
|
||||
} else {
|
||||
redis.set(redisKey, JSON.stringify(value), "EX", REDIS_EXPIRE)
|
||||
}
|
||||
})
|
||||
return null
|
||||
} else {
|
||||
redis.set(redisKey, JSON.stringify(value), "EX", REDIS_EXPIRE)
|
||||
const value = await options.getValueFun()
|
||||
if (options.noUpdate) {
|
||||
await redis.set(redisKey, JSON.stringify(value))
|
||||
} else {
|
||||
redis.set(redisKey, JSON.stringify(value), "EX", REDIS_EXPIRE)
|
||||
}
|
||||
return value
|
||||
}
|
||||
return value
|
||||
}
|
||||
} else {
|
||||
console.error("redis not ready")
|
||||
return await options.getValueFun()
|
||||
if (options.allowEmpty) {
|
||||
return null
|
||||
} else {
|
||||
return await options.getValueFun()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,22 +202,24 @@ export async function getSummary({
|
|||
cid: string
|
||||
lang?: string
|
||||
}) {
|
||||
const key = `ai_summary_${lang.replace("-", "").toLowerCase()}`
|
||||
|
||||
const summary = (await cacheGet({
|
||||
key: ["summary", cid, lang],
|
||||
allowEmpty: true,
|
||||
noUpdate: true,
|
||||
getValueFun: async () => {
|
||||
if (["en", "zh", "zh-TW", "ja"].includes(lang)) {
|
||||
const meta = await prisma.metadata.findFirst({
|
||||
where: {
|
||||
uri: `ipfs://${cid}`,
|
||||
},
|
||||
})
|
||||
if (meta) {
|
||||
if (meta?.[key as keyof Metadata]) {
|
||||
return meta?.[key as keyof Metadata]
|
||||
} else {
|
||||
lock.acquire(cid, async () => {
|
||||
let result
|
||||
await lock.acquire(cid, async () => {
|
||||
const meta = await prisma.metadata.findFirst({
|
||||
where: {
|
||||
uri: `ipfs://${cid}`,
|
||||
},
|
||||
})
|
||||
const key = `ai_summary_${lang.replace("-", "").toLowerCase()}`
|
||||
if (meta) {
|
||||
if (meta?.[key as keyof Metadata]) {
|
||||
result = meta?.[key as keyof Metadata]
|
||||
} else {
|
||||
const summary = await getOriginalSummary(cid, lang)
|
||||
if (summary) {
|
||||
await prisma.metadata.update({
|
||||
|
|
@ -228,12 +230,10 @@ export async function getSummary({
|
|||
[key as keyof Metadata]: summary,
|
||||
},
|
||||
})
|
||||
result = summary
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
lock.acquire(cid, async () => {
|
||||
}
|
||||
} else {
|
||||
const summary = await getOriginalSummary(cid, lang)
|
||||
if (summary) {
|
||||
await prisma.metadata.create({
|
||||
|
|
@ -242,13 +242,13 @@ export async function getSummary({
|
|||
[key as keyof Metadata]: summary,
|
||||
},
|
||||
})
|
||||
result = summary
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
},
|
||||
noUpdate: true,
|
||||
})) as string | undefined
|
||||
|
||||
return summary
|
||||
|
|
|
|||
Loading…
Reference in New Issue