feat(kol): cache marketplace and generation reads with singleflight

Add cache-aside + singleflight to KOL marketplace list/detail, my-subscription
prompts, and generation schema lookups. Invalidate the shared public-facing
caches when subscriptions are added/revoked (ops) or KOL profile is updated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-24 11:33:17 +08:00
parent 09c8fe1e56
commit 8761e47f78
10 changed files with 339 additions and 102 deletions
+36 -3
View File
@@ -285,14 +285,49 @@ func kolPromptListCachePrefix(tenantID int64) string {
return fmt.Sprintf("kol:prompt:list:%d:", tenantID)
}
func kolMarketplaceCachePrefix() string {
return "kol:marketplace:"
}
func kolMarketplacePackageListCachePrefix() string {
return kolMarketplaceCachePrefix() + "packages:list:"
}
func kolMarketplacePackageListCacheKey(viewerTenantID int64, params interface{}) string {
return fmt.Sprintf("%s%d:%s", kolMarketplacePackageListCachePrefix(), viewerTenantID, digestCacheKey(params))
}
func kolMarketplacePackageDetailCachePrefix() string {
return kolMarketplaceCachePrefix() + "packages:detail:"
}
func kolMarketplacePackageDetailCacheKey(viewerTenantID, packageID int64) string {
return fmt.Sprintf("%s%d:%d", kolMarketplacePackageDetailCachePrefix(), viewerTenantID, packageID)
}
func kolSubscriptionPromptListCachePrefix(tenantID int64) string {
return fmt.Sprintf("kol:subscription_prompt:list:%d:", tenantID)
}
func kolSubscriptionPromptListCacheKey(tenantID int64) string {
return kolSubscriptionPromptListCachePrefix(tenantID) + "all"
}
func kolSubscriptionPromptSchemaCachePrefix(tenantID int64) string {
return fmt.Sprintf("kol:subscription_prompt:schema:%d:", tenantID)
}
func kolSubscriptionPromptSchemaCacheKey(tenantID, subscriptionPromptID int64) string {
return fmt.Sprintf("%s%d", kolSubscriptionPromptSchemaCachePrefix(tenantID), subscriptionPromptID)
}
func InvalidateKolPublicCaches(ctx context.Context, c sharedcache.Cache) {
deleteCachePrefix(ctx, c, kolMarketplaceCachePrefix())
deleteCachePrefix(ctx, c, "kol:subscription_prompt:list:")
deleteCachePrefix(ctx, c, "kol:subscription_prompt:schema:")
deleteCachePrefix(ctx, c, "workspace:kol_cards:")
}
func invalidateKolPromptCaches(ctx context.Context, c sharedcache.Cache, tenantID int64) {
deleteCachePrefix(ctx, c, kolPromptDetailCachePrefix(tenantID))
deleteCachePrefix(ctx, c, fmt.Sprintf("kol:prompt:content:%d:", tenantID))
@@ -306,7 +341,5 @@ func InvalidateKolPromptCaches(ctx context.Context, c sharedcache.Cache) {
deleteCachePrefix(ctx, c, "kol:prompt:detail:")
deleteCachePrefix(ctx, c, "kol:prompt:content:")
deleteCachePrefix(ctx, c, "kol:prompt:list:")
deleteCachePrefix(ctx, c, "kol:subscription_prompt:list:")
deleteCachePrefix(ctx, c, "kol:subscription_prompt:schema:")
deleteCachePrefix(ctx, c, "workspace:kol_cards:")
InvalidateKolPublicCaches(ctx, c)
}