| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- import { Injectable, Logger } from '@nestjs/common';
- import { CacheKeys } from '../cache/cache-keys';
- import type { AdPoolEntry, AdType } from '../ads/ad-types';
- import { AdType as PrismaAdType } from '@prisma/mongo/client';
- import { RedisService } from '@box/db/redis/redis.service';
- import { MongoPrismaService } from '@box/db/prisma/mongo-prisma.service';
- @Injectable()
- export class AdPoolService {
- private readonly logger = new Logger(AdPoolService.name);
- constructor(
- private readonly redis: RedisService,
- private readonly mongoPrisma: MongoPrismaService,
- ) {}
- /** Rebuild all ad pools for every AdType. */
- async rebuildAllAdPools(): Promise<void> {
- const adTypes = Object.values(PrismaAdType) as AdType[];
- for (const adType of adTypes) {
- try {
- const count = await this.rebuildAdPoolByType(adType);
- this.logger.log(
- `AdPool warmup succeeded for adType=${adType}, ads=${count}`,
- );
- } catch (err) {
- this.logger.error(
- `AdPool warmup failed for adType=${adType}`,
- err instanceof Error ? err.stack : String(err),
- );
- }
- }
- }
- /** Rebuild a single ad pool keyed by AdType. */
- async rebuildAdPoolByType(adType: AdType): Promise<number> {
- const now = BigInt(Date.now());
- const ads = await this.mongoPrisma.ads.findMany({
- where: {
- adType,
- status: 1,
- startDt: { lte: now },
- OR: [{ expiryDt: BigInt(0) }, { expiryDt: { gte: now } }],
- },
- orderBy: { seq: 'asc' },
- select: {
- id: true,
- adType: true,
- advertiser: true,
- title: true,
- adsContent: true,
- adsCoverImg: true,
- adsUrl: true,
- imgSource: true,
- startDt: true,
- expiryDt: true,
- seq: true,
- },
- });
- const poolEntries: AdPoolEntry[] = ads.map((ad) => ({
- id: ad.id,
- adType: ad.adType,
- advertiser: ad.advertiser,
- title: ad.title,
- adsContent: ad.adsContent ?? null,
- adsCoverImg: ad.adsCoverImg ?? null,
- adsUrl: ad.adsUrl ?? null,
- imgSource: ad.imgSource ?? null,
- startDt: ad.startDt,
- expiryDt: ad.expiryDt,
- seq: ad.seq,
- }));
- const key = CacheKeys.appAdPoolByType(adType);
- await this.redis.atomicSwapJson([{ key, value: poolEntries }]);
- return poolEntries.length;
- }
- }
|