refactor: clean aggregate cache to event

This commit is contained in:
Innei
2022-01-18 17:05:12 +08:00
parent 7320592465
commit ab796b7853
7 changed files with 36 additions and 31 deletions

View File

@@ -2,4 +2,6 @@ export enum EventBusEvents {
EmailInit = 'email.init', EmailInit = 'email.init',
PushSearch = 'search.push', PushSearch = 'search.push',
TokenExpired = 'token.expired', TokenExpired = 'token.expired',
CleanAggregateCache = 'cache.aggregate',
} }

View File

@@ -1,11 +1,13 @@
import { forwardRef, Inject, Injectable } from '@nestjs/common' import { forwardRef, Inject, Injectable } from '@nestjs/common'
import { OnEvent } from '@nestjs/event-emitter'
import { DocumentType, ReturnModelType } from '@typegoose/typegoose' import { DocumentType, ReturnModelType } from '@typegoose/typegoose'
import { AnyParamConstructor } from '@typegoose/typegoose/lib/types' import { AnyParamConstructor } from '@typegoose/typegoose/lib/types'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { pick } from 'lodash' import { pick } from 'lodash'
import { FilterQuery } from 'mongoose' import { FilterQuery } from 'mongoose'
import { URL } from 'url' import { URL } from 'url'
import { RedisKeys } from '~/constants/cache.constant' import { CacheKeys, RedisKeys } from '~/constants/cache.constant'
import { EventBusEvents } from '~/constants/event.constant'
import { CacheService } from '~/processors/cache/cache.service' import { CacheService } from '~/processors/cache/cache.service'
import { WebEventsGateway } from '~/processors/gateway/web/events.gateway' import { WebEventsGateway } from '~/processors/gateway/web/events.gateway'
import { addYearCondition } from '~/utils/query.util' import { addYearCondition } from '~/utils/query.util'
@@ -370,4 +372,15 @@ export class AggregateService {
todayOnlineTotal: todayOnlineTotal || 0, todayOnlineTotal: todayOnlineTotal || 0,
} }
} }
@OnEvent(EventBusEvents.CleanAggregateCache, { async: true })
public clearAggregateCache() {
return Promise.all([
this.cacheService.getClient().del(CacheKeys.RSS),
this.cacheService.getClient().del(CacheKeys.RSSXmlCatch),
this.cacheService.getClient().del(CacheKeys.AggregateCatch),
this.cacheService.getClient().del(CacheKeys.SiteMapCatch),
this.cacheService.getClient().del(CacheKeys.SiteMapXmlCatch),
])
}
} }

View File

@@ -1,10 +1,11 @@
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { EventEmitter2 } from '@nestjs/event-emitter'
import { DocumentType } from '@typegoose/typegoose' import { DocumentType } from '@typegoose/typegoose'
import { isDefined, isMongoId } from 'class-validator' import { isDefined, isMongoId } from 'class-validator'
import { FilterQuery } from 'mongoose' import { FilterQuery } from 'mongoose'
import { InjectModel } from 'nestjs-typegoose' import { InjectModel } from 'nestjs-typegoose'
import { CannotFindException } from '~/common/exceptions/cant-find.exception' import { CannotFindException } from '~/common/exceptions/cant-find.exception'
import { CacheService } from '~/processors/cache/cache.service' import { EventBusEvents } from '~/constants/event.constant'
import { EventTypes } from '~/processors/gateway/events.types' import { EventTypes } from '~/processors/gateway/events.types'
import { WebEventsGateway } from '~/processors/gateway/web/events.gateway' import { WebEventsGateway } from '~/processors/gateway/web/events.gateway'
import { ImageService } from '~/processors/helper/helper.image.service' import { ImageService } from '~/processors/helper/helper.image.service'
@@ -18,7 +19,7 @@ export class NoteService {
private readonly noteModel: MongooseModel<NoteModel>, private readonly noteModel: MongooseModel<NoteModel>,
private readonly imageService: ImageService, private readonly imageService: ImageService,
private readonly webGateway: WebEventsGateway, private readonly webGateway: WebEventsGateway,
private readonly cacheService: CacheService, private readonly eventEmitter: EventEmitter2,
) { ) {
this.needCreateDefult() this.needCreateDefult()
} }
@@ -82,8 +83,8 @@ export class NoteService {
public async create(document: NoteModel) { public async create(document: NoteModel) {
const doc = await this.noteModel.create(document) const doc = await this.noteModel.create(document)
process.nextTick(async () => { process.nextTick(async () => {
this.eventEmitter.emit(EventBusEvents.CleanAggregateCache)
await Promise.all([ await Promise.all([
this.cacheService.clearAggregateCache(),
this.imageService.recordImageDimensions(this.noteModel, doc._id), this.imageService.recordImageDimensions(this.noteModel, doc._id),
doc.hide || doc.password doc.hide || doc.password
? null ? null
@@ -108,8 +109,8 @@ export class NoteService {
{ new: true }, { new: true },
) )
process.nextTick(async () => { process.nextTick(async () => {
this.eventEmitter.emit(EventBusEvents.CleanAggregateCache)
await Promise.all([ await Promise.all([
this.cacheService.clearAggregateCache(),
this.imageService.recordImageDimensions(this.noteModel, id), this.imageService.recordImageDimensions(this.noteModel, id),
this.model.findById(id).then((doc) => { this.model.findById(id).then((doc) => {
delete doc.password delete doc.password

View File

@@ -4,11 +4,12 @@ import {
Inject, Inject,
Injectable, Injectable,
} from '@nestjs/common' } from '@nestjs/common'
import { EventEmitter2 } from '@nestjs/event-emitter'
import { isDefined } from 'class-validator' import { isDefined } from 'class-validator'
import { omit } from 'lodash' import { omit } from 'lodash'
import { FilterQuery, PaginateOptions } from 'mongoose' import { FilterQuery, PaginateOptions } from 'mongoose'
import { InjectModel } from 'nestjs-typegoose' import { InjectModel } from 'nestjs-typegoose'
import { CacheService } from '~/processors/cache/cache.service' import { EventBusEvents } from '~/constants/event.constant'
import { EventTypes } from '~/processors/gateway/events.types' import { EventTypes } from '~/processors/gateway/events.types'
import { WebEventsGateway } from '~/processors/gateway/web/events.gateway' import { WebEventsGateway } from '~/processors/gateway/web/events.gateway'
import { ImageService } from '~/processors/helper/helper.image.service' import { ImageService } from '~/processors/helper/helper.image.service'
@@ -28,7 +29,7 @@ export class PostService {
private categoryService: CategoryService, private categoryService: CategoryService,
private readonly webgateway: WebEventsGateway, private readonly webgateway: WebEventsGateway,
private readonly imageService: ImageService, private readonly imageService: ImageService,
private readonly cacheService: CacheService, private readonly eventEmitter: EventEmitter2,
) {} ) {}
get model() { get model() {
@@ -61,8 +62,8 @@ export class PostService {
}) })
process.nextTick(async () => { process.nextTick(async () => {
this.eventEmitter.emit(EventBusEvents.CleanAggregateCache)
await Promise.all([ await Promise.all([
this.cacheService.clearAggregateCache(),
this.webgateway.broadcast(EventTypes.POST_CREATE, { this.webgateway.broadcast(EventTypes.POST_CREATE, {
...res.toJSON(), ...res.toJSON(),
category, category,
@@ -104,6 +105,8 @@ export class PostService {
{ new: true }, { new: true },
) )
process.nextTick(async () => { process.nextTick(async () => {
this.eventEmitter.emit(EventBusEvents.CleanAggregateCache)
// 更新图片信息缓存 // 更新图片信息缓存
await Promise.all([ await Promise.all([
this.imageService.recordImageDimensions(this.postModel, id), this.imageService.recordImageDimensions(this.postModel, id),
@@ -111,7 +114,6 @@ export class PostService {
EventTypes.POST_UPDATE, EventTypes.POST_UPDATE,
await this.postModel.findById(id), await this.postModel.findById(id),
), ),
this.cacheService.clearAggregateCache(),
]) ])
}) })

View File

@@ -1,7 +1,6 @@
import { CACHE_MANAGER, Inject, Injectable, Logger } from '@nestjs/common' import { CACHE_MANAGER, Inject, Injectable, Logger } from '@nestjs/common'
import { Cache } from 'cache-manager' import { Cache } from 'cache-manager'
import { Redis } from 'ioredis' import { Redis } from 'ioredis'
import { CacheKeys } from '~/constants/cache.constant'
// Cache 客户端管理器 // Cache 客户端管理器
@@ -47,14 +46,4 @@ export class CacheService {
public getClient() { public getClient() {
return this.redisClient return this.redisClient
} }
public clearAggregateCache() {
return Promise.all([
this.redisClient.del(CacheKeys.RSS),
this.redisClient.del(CacheKeys.RSSXmlCatch),
this.redisClient.del(CacheKeys.AggregateCatch),
this.redisClient.del(CacheKeys.SiteMapCatch),
this.redisClient.del(CacheKeys.SiteMapXmlCatch),
])
}
} }

View File

@@ -1,5 +1,14 @@
/**
* 服务集群工具
*/
import cluster from 'cluster' import cluster from 'cluster'
import { EventBusEvents } from '~/constants/event.constant' import { EventBusEvents } from '~/constants/event.constant'
/**
* Worker 事件 Emit
* @param event
* @param data
*/
export const workerEmit = (event: EventBusEvents, data?: any) => { export const workerEmit = (event: EventBusEvents, data?: any) => {
if (cluster.isWorker) { if (cluster.isWorker) {
process.send({ event, data, workerId: cluster.worker.id }) process.send({ event, data, workerId: cluster.worker.id })

View File

@@ -1,6 +1,5 @@
import IORedis from 'ioredis' import IORedis from 'ioredis'
import RedisMemoryServer from 'redis-memory-server' import RedisMemoryServer from 'redis-memory-server'
import { CacheKeys } from '~/constants/cache.constant'
export class MockCacheService { export class MockCacheService {
private client: IORedis.Redis private client: IORedis.Redis
@@ -23,16 +22,6 @@ export class MockCacheService {
public getClient() { public getClient() {
return this.redisClient return this.redisClient
} }
public clearAggregateCache() {
return Promise.all([
this.redisClient.del(CacheKeys.RSS),
this.redisClient.del(CacheKeys.RSSXmlCatch),
this.redisClient.del(CacheKeys.AggregateCatch),
this.redisClient.del(CacheKeys.SiteMapCatch),
this.redisClient.del(CacheKeys.SiteMapXmlCatch),
])
}
} }
export const createMockRedis = async () => { export const createMockRedis = async () => {