mirror of
https://github.com/saltbo/zpan.git
synced 2026-08-28 15:51:29 +08:00
1d58d5b80d
* feat(image-hosting): add custom domain providers * test(image-hosting): cover custom domain provider flows
86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
// CF Workers scheduled() handler.
|
|
|
|
import { createQuotaRepo } from '../server/adapters/repos/quota'
|
|
import { createDeps } from '../server/composition'
|
|
import { createCloudflarePlatform } from '../server/platform/cloudflare'
|
|
import { syncPendingRemoteDownloadUsageReports } from '../server/usecases/downloads/remote-download-usage'
|
|
import { purgeExpiredTrash, resolveTrashRetentionDays } from '../server/usecases/object'
|
|
import { purgeExpiredResourceChanges } from '../server/usecases/resource-changes'
|
|
import { reconcileImageDomains } from '../server/usecases/site/image-domain-provider'
|
|
import { INSTANCE_TELEMETRY_CRON, reportInstanceTelemetry } from '../server/usecases/site/instance-telemetry'
|
|
import { runLicensingRefresh } from '../server/usecases/site/licensing'
|
|
import { syncPendingCloudTrafficReports } from '../server/usecases/store/traffic-metering'
|
|
import { ZPAN_CLOUD_URL_DEFAULT } from '../shared/constants'
|
|
|
|
// Subset of the worker Env used by the scheduled handler.
|
|
// The full Env is defined in bootstrap.ts; this avoids circular imports.
|
|
export interface ScheduledEnv {
|
|
DB: D1Database
|
|
ZPAN_CLOUD_URL?: string
|
|
ZPAN_TELEMETRY_ALLOW_IP?: string
|
|
ZPAN_TRASH_RETENTION_DAYS?: string
|
|
[key: string]: unknown
|
|
}
|
|
|
|
const TRAFFIC_SYNC_CRON = '*/10 * * * *'
|
|
const STATS_ROLLUP_CRON = '10 * * * *'
|
|
const QUOTA_RESET_CRON = '0 0 1 * *'
|
|
const TRASH_PURGE_CRON = '0 4 * * *'
|
|
type ScheduledTrigger = Pick<ScheduledEvent, 'cron'>
|
|
|
|
function envAllowsIp(value: string | undefined): boolean {
|
|
return !['0', 'false', 'no', 'off'].includes(value?.trim().toLowerCase() ?? '')
|
|
}
|
|
|
|
export async function handleScheduled(event: ScheduledTrigger, env: ScheduledEnv): Promise<void> {
|
|
const platform = createCloudflarePlatform(env)
|
|
const deps = createDeps(platform)
|
|
const cloudBaseUrl = env.ZPAN_CLOUD_URL ?? ZPAN_CLOUD_URL_DEFAULT
|
|
if (event.cron === TRAFFIC_SYNC_CRON) {
|
|
await deps.quota.reconcileFreePlanBaselines()
|
|
await Promise.all([
|
|
syncPendingCloudTrafficReports(deps, { cloudBaseUrl }),
|
|
syncPendingRemoteDownloadUsageReports(deps, { cloudBaseUrl }),
|
|
])
|
|
return
|
|
}
|
|
|
|
if (event.cron === STATS_ROLLUP_CRON) {
|
|
const now = new Date()
|
|
await Promise.all([
|
|
deps.adminStats.refreshHourlyRollups(now),
|
|
deps.webdavState.purgeExpiredLocks(),
|
|
purgeExpiredResourceChanges(deps, now),
|
|
reconcileImageDomains(deps),
|
|
])
|
|
return
|
|
}
|
|
|
|
if (event.cron === QUOTA_RESET_CRON) {
|
|
await createQuotaRepo(platform.db).resetExpiredTrafficQuotas()
|
|
return
|
|
}
|
|
|
|
if (event.cron === TRASH_PURGE_CRON) {
|
|
await purgeExpiredTrash(deps, resolveTrashRetentionDays(env.ZPAN_TRASH_RETENTION_DAYS))
|
|
return
|
|
}
|
|
|
|
if (event.cron === INSTANCE_TELEMETRY_CRON) {
|
|
await reportInstanceTelemetry(deps, {
|
|
config: {
|
|
allowIp: envAllowsIp(env.ZPAN_TELEMETRY_ALLOW_IP),
|
|
},
|
|
cron: event.cron,
|
|
trigger: 'scheduled',
|
|
runtime: {
|
|
runtime: 'workerd',
|
|
platform: 'cloudflare-workers',
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
await runLicensingRefresh(deps, cloudBaseUrl)
|
|
}
|