feat: cacheGet options

This commit is contained in:
DIYgod 2023-03-02 20:17:47 +00:00
parent c332b72fee
commit 5b2bf56aee
No known key found for this signature in database
6 changed files with 94 additions and 68 deletions

View File

@ -26,39 +26,39 @@ let redisPromise: Promise<Redis> = new Promise((resolve, reject) => {
export const getRedis = () => redisPromise
export async function cacheGet(
key: string | (Record<string, any> | string | undefined)[],
getValueFun: () => Promise<any>,
noUpdate?: boolean,
) {
export async function cacheGet(options: {
key: string | (Record<string, any> | string | undefined)[]
getValueFun: () => Promise<any>
noUpdate?: boolean
}) {
const redis = await redisPromise
if (redis && redis.status === "ready") {
let redisKey: string
if (Array.isArray(key)) {
redisKey = key
if (Array.isArray(options.key)) {
redisKey = options.key
.map((k) => (typeof k === "string" ? k : JSON.stringify(k)))
.join(":")
} else {
redisKey = key
redisKey = options.key
}
const cacheValue = await redis.get(redisKey)
if (cacheValue) {
if (!noUpdate) {
if (!options.noUpdate) {
setTimeout(() => {
getValueFun().then((value) => {
options.getValueFun().then((value) => {
redis.set(redisKey, JSON.stringify(value), "EX", REDIS_EXPIRE)
})
}, Math.random() * REDIS_REFRESH)
}
return JSON.parse(cacheValue)
} else {
const value = await getValueFun()
const value = await options.getValueFun()
redis.set(redisKey, JSON.stringify(value), "EX", REDIS_EXPIRE)
return value
}
} else {
console.error("redis not ready")
return await getValueFun()
return await options.getValueFun()
}
}

View File

@ -18,44 +18,47 @@ export default async function handler(
const OUR_DOMAIN_SUFFIX = `.${OUR_DOMAIN}`
if (realHost && realHost !== OUR_DOMAIN) {
result = await cacheGet(["host2handle", realHost], async () => {
if (realHost.endsWith(OUR_DOMAIN_SUFFIX)) {
const subdomain = realHost.replace(OUR_DOMAIN_SUFFIX, "")
const res = await fetch(
`https://indexer.crossbell.io/v1/handles/${subdomain}/character`,
)
const char = await res.json()
const customDomain =
char?.metadata?.content?.attributes?.find(
(a: any) => a.trait_type === "xlog_custom_domain",
)?.value || ""
if (customDomain) {
return {
redirect: /^https?:\/\//.test(customDomain)
? customDomain
: `https://${customDomain}`,
subdomain: subdomain,
result = await cacheGet({
key: ["host2handle", realHost],
getValueFun: async () => {
if (realHost.endsWith(OUR_DOMAIN_SUFFIX)) {
const subdomain = realHost.replace(OUR_DOMAIN_SUFFIX, "")
const res = await fetch(
`https://indexer.crossbell.io/v1/handles/${subdomain}/character`,
)
const char = await res.json()
const customDomain =
char?.metadata?.content?.attributes?.find(
(a: any) => a.trait_type === "xlog_custom_domain",
)?.value || ""
if (customDomain) {
return {
redirect: /^https?:\/\//.test(customDomain)
? customDomain
: `https://${customDomain}`,
subdomain: subdomain,
}
} else {
return {
subdomain: subdomain,
}
}
} else {
const res = await fetch(
`https://cloudflare-dns.com/dns-query?name=_xlog-challenge.${realHost}&type=TXT`,
{
headers: {
accept: "application/dns-json",
},
},
)
const txt = await res.json()
const tenant = txt?.Answer?.[0]?.data.replace(/^"|"$/g, "")
return {
subdomain: subdomain,
subdomain: tenant,
}
}
} else {
const res = await fetch(
`https://cloudflare-dns.com/dns-query?name=_xlog-challenge.${realHost}&type=TXT`,
{
headers: {
accept: "application/dns-json",
},
},
)
const txt = await res.json()
const tenant = txt?.Answer?.[0]?.data.replace(/^"|"$/g, "")
return {
subdomain: tenant,
}
}
},
})
}

View File

@ -15,7 +15,7 @@ export default async function handler(
return
}
const redis = getRedis()
const redis = await getRedis()
const redisKey = `nfts/${query.address}`
let cache
@ -30,9 +30,9 @@ export default async function handler(
result.list.map(async (nft: Asset) => {
if (!nft.items?.[0].mime_type && nft.items?.[0]?.address) {
try {
const mime_type = await cacheGet(
`nft-mimetype/${nft.items[0].address}`,
async () => {
const mime_type = await cacheGet({
key: `nft-mimetype/${nft.items[0].address}`,
getValueFun: async () => {
const head = await fetch(
`${nft.items![0].address!.replace(
IPFS_GATEWAY,
@ -44,7 +44,7 @@ export default async function handler(
)
return head.headers.get("content-type")
},
)
})
nft.items[0].mime_type = mime_type
} catch (error) {
console.warn(error)

View File

@ -6,9 +6,9 @@ import { getNoteSlug } from "~/lib/helpers"
export async function getIdBySlug(slug: string, handle: string) {
slug = (slug as string)?.toLowerCase?.()
const result = await cacheGet(
["slug2id", handle, slug],
async () => {
const result = await cacheGet({
key: ["slug2id", handle, slug],
getValueFun: async () => {
let note
let cursor = ""
@ -47,8 +47,8 @@ export async function getIdBySlug(slug: string, handle: string) {
}
}
},
true,
)
noUpdate: true,
})
// revalidate
if (result) {

View File

@ -20,7 +20,10 @@ export const fetchGetPage = async (
input.pageId = `${slug2Id.characterId}-${slug2Id.noteId}`
}
delete input.page
return cacheGet(key, () => pageModel.getPage(input))
return cacheGet({
key,
getValueFun: () => pageModel.getPage(input),
})
})
}
@ -32,12 +35,14 @@ export const prefetchGetPagesBySite = async (
await queryClient.prefetchInfiniteQuery({
queryKey: key,
queryFn: async ({ pageParam }) => {
return cacheGet(key, () =>
pageModel.getPagesBySite({
...input,
cursor: pageParam,
}),
)
return cacheGet({
key,
getValueFun: () =>
pageModel.getPagesBySite({
...input,
cursor: pageParam,
}),
})
},
getNextPageParam: (lastPage) => lastPage.cursor || undefined,
})
@ -49,6 +54,9 @@ export const fetchGetPagesBySite = async (
) => {
const key = ["getPagesBySite", input.site, input]
return await queryClient.fetchQuery(key, async () => {
return cacheGet(key, () => pageModel.getPagesBySite(input))
return cacheGet({
key,
getValueFun: () => pageModel.getPagesBySite(input),
})
})
}

View File

@ -8,14 +8,20 @@ export const prefetchGetSite = async (
) => {
const key = ["getSite", input]
await queryClient.prefetchQuery(key, async () => {
return cacheGet(key, () => siteModel.getSite(input))
return cacheGet({
key,
getValueFun: () => siteModel.getSite(input),
})
})
}
export const fetchGetSite = async (input: string, queryClient: QueryClient) => {
const key = ["getSite", input]
return await queryClient.fetchQuery(key, async () => {
return cacheGet(key, () => siteModel.getSite(input))
return cacheGet({
key,
getValueFun: () => siteModel.getSite(input),
})
})
}
@ -25,7 +31,10 @@ export const prefetchGetSiteSubscriptions = async (
) => {
const key = ["getSiteSubscriptions", input]
await queryClient.prefetchQuery(key, async () => {
return cacheGet(key, () => siteModel.getSiteSubscriptions(input))
return cacheGet({
key,
getValueFun: () => siteModel.getSiteSubscriptions(input),
})
})
}
@ -35,7 +44,10 @@ export const prefetchGetSiteToSubscriptions = async (
) => {
const key = ["getSiteToSubscriptions", input]
await queryClient.prefetchQuery(key, async () => {
return cacheGet(key, () => siteModel.getSiteToSubscriptions(input))
return cacheGet({
key,
getValueFun: () => siteModel.getSiteToSubscriptions(input),
})
})
}
@ -45,6 +57,9 @@ export const prefetchGetSites = async (
) => {
const key = ["getSites", input]
await queryClient.fetchQuery(key, async () => {
return cacheGet(key, () => siteModel.getSites(input))
return cacheGet({
key,
getValueFun: () => siteModel.getSites(input),
})
})
}