fix: refactor fetching and refetch logic
This commit is contained in:
@@ -1,89 +0,0 @@
|
||||
import type { SourceID, SourceResponse } from "@shared/types"
|
||||
import { getters } from "#/getters"
|
||||
import { getCacheTable } from "#/database/cache"
|
||||
import type { CacheInfo } from "#/types"
|
||||
|
||||
export default defineEventHandler(async (event): Promise<SourceResponse> => {
|
||||
try {
|
||||
let id = getRouterParam(event, "id") as SourceID
|
||||
const query = getQuery(event)
|
||||
const latest = query.latest !== undefined && query.latest !== "false"
|
||||
const isValid = (id: SourceID) => !id || !sources[id] || !getters[id]
|
||||
|
||||
if (isValid(id)) {
|
||||
const redirectID = sources?.[id]?.redirect
|
||||
if (redirectID) id = redirectID
|
||||
if (isValid(id)) throw new Error("Invalid source id")
|
||||
}
|
||||
|
||||
const cacheTable = await getCacheTable()
|
||||
const now = Date.now()
|
||||
let cache: CacheInfo
|
||||
if (cacheTable) {
|
||||
cache = await cacheTable.get(id)
|
||||
if (cache) {
|
||||
// interval 刷新间隔,对于缓存失效也要执行的。本质上表示本来内容更新就很慢,这个间隔内可能内容压根不会更新。
|
||||
// 默认 10 分钟,是低于 TTL 的,但部分 Source 的更新间隔会超过 TTL,甚至有的一天更新一次。
|
||||
const interval = sources[id].interval
|
||||
if (now - cache.updated < interval) {
|
||||
return {
|
||||
status: "success",
|
||||
id,
|
||||
updatedTime: now,
|
||||
items: cache.data,
|
||||
}
|
||||
}
|
||||
|
||||
// 而 TTL 缓存失效时间,在时间范围内,就算内容更新了也要用这个缓存。
|
||||
// 复用缓存是不会更新时间的。
|
||||
if (now - cache.updated < TTL) {
|
||||
// 有 latest
|
||||
// 没有 latest,但服务器禁止登录
|
||||
|
||||
// 没有 latest
|
||||
// 有 latest,服务器可以登录但没有登录
|
||||
if (!latest || (!event.context.disabledLogin && !event.context.user)) {
|
||||
return {
|
||||
status: "cache",
|
||||
id,
|
||||
updatedTime: cache.updated,
|
||||
items: cache.data,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const newData = (await getters[id]()).slice(0, 30)
|
||||
if (cacheTable && newData) {
|
||||
if (event.context.waitUntil) event.context.waitUntil(cacheTable.set(id, newData))
|
||||
else await cacheTable.set(id, newData)
|
||||
}
|
||||
logger.success(`fetch ${id} latest`)
|
||||
return {
|
||||
status: "success",
|
||||
id,
|
||||
updatedTime: now,
|
||||
items: newData,
|
||||
}
|
||||
} catch (e) {
|
||||
if (cache!) {
|
||||
return {
|
||||
status: "cache",
|
||||
id,
|
||||
updatedTime: cache.updated,
|
||||
items: cache.data,
|
||||
}
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
logger.error(e)
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
message: e instanceof Error ? e.message : "Internal Server Error",
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { SourceID, SourceResponse } from "@shared/types"
|
||||
import { getCacheTable } from "#/database/cache"
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const { sources: _ }: { sources: SourceID[] } = await readBody(event)
|
||||
const cacheTable = await getCacheTable()
|
||||
const ids = _?.filter(k => sources[k])
|
||||
if (ids?.length && cacheTable) {
|
||||
const caches = await cacheTable.getEntire(ids)
|
||||
const now = Date.now()
|
||||
return caches.map(cache => ({
|
||||
status: "cache",
|
||||
id: cache.id,
|
||||
items: cache.items,
|
||||
updatedTime: now - cache.updated < sources[cache.id].interval ? now : cache.updated,
|
||||
})) as SourceResponse[]
|
||||
}
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
})
|
||||
@@ -1,14 +0,0 @@
|
||||
import { getCacheTable } from "#/database/cache"
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const { sources } = await readBody(event)
|
||||
const cacheTable = await getCacheTable()
|
||||
if (sources && cacheTable) {
|
||||
const data = await cacheTable.getEntries(sources)
|
||||
return data
|
||||
}
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
})
|
||||
@@ -17,20 +17,21 @@ export default defineEventHandler(async (event): Promise<SourceResponse> => {
|
||||
}
|
||||
|
||||
const cacheTable = await getCacheTable()
|
||||
// Date.now() in Cloudflare Worker will not update throughout the entire runtime.
|
||||
const now = Date.now()
|
||||
let cache: CacheInfo
|
||||
let cache: CacheInfo | undefined
|
||||
if (cacheTable) {
|
||||
cache = await cacheTable.get(id)
|
||||
if (cache) {
|
||||
// if (cache) {
|
||||
// interval 刷新间隔,对于缓存失效也要执行的。本质上表示本来内容更新就很慢,这个间隔内可能内容压根不会更新。
|
||||
// 默认 10 分钟,是低于 TTL 的,但部分 Source 的更新间隔会超过 TTL,甚至有的一天更新一次。
|
||||
const interval = sources[id].interval
|
||||
if (now - cache.updated < interval) {
|
||||
if (now - cache.updated < sources[id].interval) {
|
||||
return {
|
||||
status: "success",
|
||||
id,
|
||||
updatedTime: now,
|
||||
items: cache.data,
|
||||
items: cache.items,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +48,7 @@ export default defineEventHandler(async (event): Promise<SourceResponse> => {
|
||||
status: "cache",
|
||||
id,
|
||||
updatedTime: cache.updated,
|
||||
items: cache.data,
|
||||
items: cache.items,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +57,7 @@ export default defineEventHandler(async (event): Promise<SourceResponse> => {
|
||||
|
||||
try {
|
||||
const newData = (await getters[id]()).slice(0, 30)
|
||||
if (cacheTable && newData) {
|
||||
if (cacheTable && newData.length) {
|
||||
if (event.context.waitUntil) event.context.waitUntil(cacheTable.set(id, newData))
|
||||
else await cacheTable.set(id, newData)
|
||||
}
|
||||
@@ -73,7 +74,7 @@ export default defineEventHandler(async (event): Promise<SourceResponse> => {
|
||||
status: "cache",
|
||||
id,
|
||||
updatedTime: cache.updated,
|
||||
items: cache.data,
|
||||
items: cache.items,
|
||||
}
|
||||
} else {
|
||||
throw e
|
||||
|
||||
Reference in New Issue
Block a user