perf(public): 公开读路径进程内分域缓存——meta/goods/matrix 版本域 + TTL 兜底 + in-flight 合并
- PublicCacheService:分域版本号失效(bump 即作废,不等 TTL)、loader 期间 bump 的竞态防护(返回但不回写)、并发 miss 单飞、PUBLIC_CACHE_DISABLED /TTL_MS/MAX_ENTRIES 应急开关;@Global 模块 - PublicService 六端点接缓存:列表缓存全量物化(分页切片在缓存外按请求执行, 修复'所有页返回第一页'的切片缓存错误)、详情/首页/树/标签组/树序元数据/ 族最低价聚合各按依赖域缓存 - 全写路径挂钩 bump:admin CRUD(goods/categories/countries/tags/tag-groups/ positions/origin-goods 标签)、sync 三同步、族重算、整理全家桶—— 事务提交成功后失效对应域,product-families 经 recompute 天然覆盖 - 测试:PublicCacheService 单测 13 例 + 失效链路集成 8 例(读命中/写后立即可见 端到端/每条写路径域断言);既有两套件测数据语义改为显式禁缓存
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { PublicCacheService } from '../public/public-cache.service';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import {
|
||||
BadRequestException,
|
||||
@@ -30,6 +31,7 @@ describe('GoodsService', () => {
|
||||
beforeAll(async () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
providers: [
|
||||
PublicCacheService,
|
||||
GoodsService,
|
||||
PrismaService,
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ import { BatchPriorityDto } from './dto/batch-priority.dto';
|
||||
import { GoodDetailDto, GoodDto, PaginatedGoods } from './dto/good.dto';
|
||||
import { SyncService } from '../sync/sync.service';
|
||||
import { FamilyRecomputeService } from '../product-families/family-recompute.service';
|
||||
import { PublicCacheService } from '../public/public-cache.service';
|
||||
import { isAutoTagGroupName } from '../product-families/auto-tag-rules';
|
||||
import { randomUUID } from 'crypto';
|
||||
import {
|
||||
@@ -120,6 +121,7 @@ export class GoodsService {
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly syncService: SyncService,
|
||||
private readonly familyRecompute: FamilyRecomputeService,
|
||||
private readonly publicCache: PublicCacheService,
|
||||
) {}
|
||||
|
||||
async findAll(query: QueryGoodDto): Promise<PaginatedGoods> {
|
||||
@@ -240,6 +242,7 @@ export class GoodsService {
|
||||
// 建商品后把链接有效标签镜像到该商品(纯聚合,不派生——派生在整理流程)
|
||||
await this.familyRecompute.mirrorLinkTagsToGoods(BigInt(result.originGoodId));
|
||||
}
|
||||
this.publicCache.bump('goods');
|
||||
if (
|
||||
result.originGood?.source === 'SDS' &&
|
||||
result.originGood.sdsGoodId &&
|
||||
@@ -314,6 +317,7 @@ export class GoodsService {
|
||||
}
|
||||
return good.id;
|
||||
});
|
||||
this.publicCache.bump('goods');
|
||||
if (family) this.familyRecompute.enqueue(family.id);
|
||||
return this.findOne(goodId);
|
||||
}
|
||||
@@ -369,6 +373,7 @@ export class GoodsService {
|
||||
await tx.good.update({ where: { id }, data: goodData });
|
||||
}
|
||||
});
|
||||
this.publicCache.bump('goods');
|
||||
return this.findOne(id);
|
||||
}
|
||||
|
||||
@@ -495,6 +500,7 @@ export class GoodsService {
|
||||
// 归族联动后重算矩阵(成员变化 → 自动重算,结构化聚合)
|
||||
await this.familyRecompute.recomputeFamily(familyIdForTags);
|
||||
}
|
||||
this.publicCache.bump('goods');
|
||||
if (
|
||||
result.originGood?.source === 'SDS' &&
|
||||
result.originGood.sdsGoodId &&
|
||||
@@ -522,6 +528,7 @@ export class GoodsService {
|
||||
}
|
||||
}
|
||||
});
|
||||
this.publicCache.bump('goods');
|
||||
return { id: id.toString() };
|
||||
}
|
||||
|
||||
@@ -539,6 +546,7 @@ export class GoodsService {
|
||||
}
|
||||
return { count: dto.items.length };
|
||||
});
|
||||
this.publicCache.bump('goods');
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -634,6 +642,7 @@ export class GoodsService {
|
||||
)) {
|
||||
this.syncService.queueProductDetailSync(goodId);
|
||||
}
|
||||
this.publicCache.bump('goods');
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user