fix: worker event bus emit

This commit is contained in:
Innei
2022-01-18 13:39:28 +08:00
parent c80048f9ce
commit bcc90f90b9
20 changed files with 71 additions and 19 deletions

View File

@@ -4,8 +4,10 @@ import os from 'os'
export class Cluster { export class Cluster {
static register(workers: Number, callback: Function): void { static register(workers: Number, callback: Function): void {
if (cluster.isPrimary) { if (cluster.isPrimary) {
consola.info(`Primary server started on ${process.pid}`) const cpus = os.cpus().length
consola.info(`Primary server started on ${process.pid}`)
consola.info('CPU:' + cpus)
//ensure workers exit cleanly //ensure workers exit cleanly
process.on('SIGINT', function () { process.on('SIGINT', function () {
consola.info('Cluster shutting down...') consola.info('Cluster shutting down...')
@@ -16,12 +18,20 @@ export class Cluster {
process.exit(0) process.exit(0)
}) })
const cpus = os.cpus().length
if (workers > cpus) workers = cpus if (workers > cpus) workers = cpus
for (let i = 0; i < workers; i++) { for (let i = 0; i < workers; i++) {
cluster.fork() cluster.fork()
} }
cluster.on('fork', function (worker) {
worker.on('message', function (msg) {
Object.keys(cluster.workers).forEach(function (id) {
cluster.workers[id].send(msg)
})
})
})
cluster.on('online', function (worker) { cluster.on('online', function (worker) {
consola.info('Worker %s is online', worker.process.pid) consola.info('Worker %s is online', worker.process.pid)
}) })

View File

@@ -15,7 +15,7 @@ import { resolve } from 'path'
import { HTTP_REQUEST_TIME } from '~/constants/meta.constant' import { HTTP_REQUEST_TIME } from '~/constants/meta.constant'
import { LOGGER_DIR } from '~/constants/path.constant' import { LOGGER_DIR } from '~/constants/path.constant'
import { REFLECTOR } from '~/constants/system.constant' import { REFLECTOR } from '~/constants/system.constant'
import { isDev } from '~/utils/index.util' import { isDev } from '~/utils'
import { getIp } from '../../utils/ip.util' import { getIp } from '../../utils/ip.util'
import { LoggingInterceptor } from '../interceptors/logging.interceptor' import { LoggingInterceptor } from '../interceptors/logging.interceptor'
type myError = { type myError = {

View File

@@ -1,7 +1,7 @@
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common' import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'
import { AuthGuard as _AuthGuard } from '@nestjs/passport' import { AuthGuard as _AuthGuard } from '@nestjs/passport'
import { mockUser1 } from '~/mock/user.mock' import { mockUser1 } from '~/mock/user.mock'
import { isTest } from '~/utils/index.util' import { isTest } from '~/utils'
import { getNestExecutionContextRequest } from '~/utils/nest.util' import { getNestExecutionContextRequest } from '~/utils/nest.util'
/** /**

View File

@@ -10,7 +10,7 @@ import {
Injectable, Injectable,
} from '@nestjs/common' } from '@nestjs/common'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
import { isDev } from '~/utils/index.util' import { isDev } from '~/utils'
import { getNestExecutionContextRequest } from '~/utils/nest.util' import { getNestExecutionContextRequest } from '~/utils/nest.util'
@Injectable() @Injectable()

View File

@@ -1,6 +1,6 @@
import { homedir } from 'os' import { homedir } from 'os'
import { join } from 'path' import { join } from 'path'
import { isDev } from '~/utils/index.util' import { isDev } from '~/utils'
export const HOME = homedir() export const HOME = homedir()

View File

@@ -7,7 +7,7 @@ import {
import { isDefined } from 'class-validator' import { isDefined } from 'class-validator'
import { cloneDeep, isArrayLike, isObjectLike } from 'lodash' import { cloneDeep, isArrayLike, isObjectLike } from 'lodash'
import { map } from 'rxjs' import { map } from 'rxjs'
import { getAvatar } from '~/utils/index.util' import { getAvatar } from '~/utils'
import { getNestExecutionContextRequest } from '~/utils/nest.util' import { getNestExecutionContextRequest } from '~/utils/nest.util'
@Injectable() @Injectable()
export class CommentFilterEmailInterceptor implements NestInterceptor { export class CommentFilterEmailInterceptor implements NestInterceptor {

View File

@@ -8,7 +8,7 @@ import {
import { BeAnObject } from '@typegoose/typegoose/lib/types' import { BeAnObject } from '@typegoose/typegoose/lib/types'
import { Query, Types } from 'mongoose' import { Query, Types } from 'mongoose'
import { BaseModel } from '~/shared/model/base.model' import { BaseModel } from '~/shared/model/base.model'
import { getAvatar } from '~/utils/index.util' import { getAvatar } from '~/utils'
import { NoteModel } from '../note/note.model' import { NoteModel } from '../note/note.model'
import { PageModel } from '../page/page.model' import { PageModel } from '../page/page.model'
import { PostModel } from '../post/post.model' import { PostModel } from '../post/post.model'

View File

@@ -11,7 +11,7 @@ import {
ReplyMailType, ReplyMailType,
} from '~/processors/helper/helper.email.service' } from '~/processors/helper/helper.email.service'
import { WriteBaseModel } from '~/shared/model/base.model' import { WriteBaseModel } from '~/shared/model/base.model'
import { hasChinese } from '~/utils/index.util' import { hasChinese } from '~/utils'
import { ConfigsService } from '../configs/configs.service' import { ConfigsService } from '../configs/configs.service'
import { UserService } from '../user/user.service' import { UserService } from '../user/user.service'
import BlockedKeywords from './block-keywords.json' import BlockedKeywords from './block-keywords.json'

View File

@@ -10,6 +10,7 @@ import { BeAnObject } from '@typegoose/typegoose/lib/types'
import camelcaseKeys from 'camelcase-keys' import camelcaseKeys from 'camelcase-keys'
import { ClassConstructor, plainToClass } from 'class-transformer' import { ClassConstructor, plainToClass } from 'class-transformer'
import { validateSync, ValidatorOptions } from 'class-validator' import { validateSync, ValidatorOptions } from 'class-validator'
import cluster from 'cluster'
import { cloneDeep, mergeWith } from 'lodash' import { cloneDeep, mergeWith } from 'lodash'
import { LeanDocument } from 'mongoose' import { LeanDocument } from 'mongoose'
import { InjectModel } from 'nestjs-typegoose' import { InjectModel } from 'nestjs-typegoose'
@@ -17,7 +18,7 @@ import { API_VERSION } from '~/app.config'
import { RedisKeys } from '~/constants/cache.constant' import { RedisKeys } from '~/constants/cache.constant'
import { EventBusEvents } from '~/constants/event.constant' import { EventBusEvents } from '~/constants/event.constant'
import { CacheService } from '~/processors/cache/cache.service' import { CacheService } from '~/processors/cache/cache.service'
import { sleep } from '~/utils/index.util' import { sleep, workerEmit } from '~/utils'
import { getRedisKey } from '~/utils/redis.util' import { getRedisKey } from '~/utils/redis.util'
import * as optionDtos from '../configs/configs.dto' import * as optionDtos from '../configs/configs.dto'
import { UserModel } from '../user/user.model' import { UserModel } from '../user/user.model'
@@ -201,7 +202,11 @@ export class ConfigsService {
this.validWithDto(MailOptionsDto, value), this.validWithDto(MailOptionsDto, value),
) )
if (option.enable) { if (option.enable) {
if (cluster.isPrimary) {
this.eventEmitter.emit(EventBusEvents.EmailInit) this.eventEmitter.emit(EventBusEvents.EmailInit)
} else {
workerEmit(EventBusEvents.EmailInit)
}
} }
return option return option

View File

@@ -6,7 +6,7 @@ import {
EmailService, EmailService,
LinkApplyEmailType, LinkApplyEmailType,
} from '~/processors/helper/helper.email.service' } from '~/processors/helper/helper.email.service'
import { isDev } from '~/utils/index.util' import { isDev } from '~/utils'
import { ConfigsService } from '../configs/configs.service' import { ConfigsService } from '../configs/configs.service'
import { LinkModel, LinkState, LinkType } from './link.model' import { LinkModel, LinkState, LinkType } from './link.model'

View File

@@ -8,7 +8,7 @@ import { CacheService } from '~/processors/cache/cache.service'
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'
import { deleteKeys } from '~/utils/index.util' import { deleteKeys } from '~/utils'
import { NoteModel } from './note.model' import { NoteModel } from './note.model'
@Injectable() @Injectable()

View File

@@ -15,7 +15,7 @@ import { CurrentUser } from '~/common/decorator/current-user.decorator'
import { IpLocation, IpRecord } from '~/common/decorator/ip.decorator' import { IpLocation, IpRecord } from '~/common/decorator/ip.decorator'
import { ApiName } from '~/common/decorator/openapi.decorator' import { ApiName } from '~/common/decorator/openapi.decorator'
import { IsMaster } from '~/common/decorator/role.decorator' import { IsMaster } from '~/common/decorator/role.decorator'
import { getAvatar } from '~/utils/index.util' import { getAvatar } from '~/utils'
import { AuthService } from '../auth/auth.service' import { AuthService } from '../auth/auth.service'
import { LoginDto, UserDto, UserPatchDto } from './user.dto' import { LoginDto, UserDto, UserPatchDto } from './user.dto'
import { UserDocument, UserModel } from './user.model' import { UserDocument, UserModel } from './user.model'

View File

@@ -12,7 +12,7 @@ import { nanoid } from 'nanoid'
import { InjectModel } from 'nestjs-typegoose' import { InjectModel } from 'nestjs-typegoose'
import { RedisKeys } from '~/constants/cache.constant' import { RedisKeys } from '~/constants/cache.constant'
import { CacheService } from '~/processors/cache/cache.service' import { CacheService } from '~/processors/cache/cache.service'
import { getAvatar, sleep } from '~/utils/index.util' import { getAvatar, sleep } from '~/utils'
import { getRedisKey } from '~/utils/redis.util' import { getRedisKey } from '~/utils/redis.util'
import { AuthService } from '../auth/auth.service' import { AuthService } from '../auth/auth.service'
import { UserDocument, UserModel } from './user.model' import { UserDocument, UserModel } from './user.model'

View File

@@ -1,5 +1,6 @@
import { Injectable, Logger } from '@nestjs/common' import { Injectable, Logger } from '@nestjs/common'
import { OnEvent } from '@nestjs/event-emitter' import { OnEvent } from '@nestjs/event-emitter'
import cluster from 'cluster'
import { render } from 'ejs' import { render } from 'ejs'
import { createTransport } from 'nodemailer' import { createTransport } from 'nodemailer'
import { EventBusEvents } from '~/constants/event.constant' import { EventBusEvents } from '~/constants/event.constant'
@@ -27,6 +28,22 @@ export class EmailService {
) { ) {
this.init() this.init()
this.logger = new Logger(EmailService.name) this.logger = new Logger(EmailService.name)
if (cluster.isWorker) {
// listen email option change in node cluster
process.on('message', (message: any) => {
const { event } = message
switch (event) {
case EventBusEvents.EmailInit:
this.init()
break
default:
break
}
})
}
} }
async readTemplate(type: ReplyMailType) { async readTemplate(type: ReplyMailType) {

View File

@@ -0,0 +1,7 @@
import cluster from 'cluster'
import { EventBusEvents } from '~/constants/event.constant'
export const workerEmit = (event: EventBusEvents, data?: any) => {
if (cluster.isWorker) {
process.send({ event, data, workerId: cluster.worker.id })
}
}

View File

@@ -1,6 +1,7 @@
import consola_, { FancyReporter, LogLevel } from 'consola' import consola_, { FancyReporter, LogLevel } from 'consola'
import { argv } from 'zx' import { argv } from 'zx'
import { isDev } from './index.util' import { isDev } from './tool.util'
class DateTimeReporter extends FancyReporter { class DateTimeReporter extends FancyReporter {
formatDate(date: Date) { formatDate(date: Date) {
return date.toLocaleString(undefined, { return date.toLocaleString(undefined, {

View File

@@ -1,6 +1,6 @@
import { isDev } from '.'
import { consola } from './consola.util' import { consola } from './consola.util'
import './dayjs.util' import './dayjs.util'
import { isDev } from './index.util'
console.debug = (...rest) => { console.debug = (...rest) => {
if (isDev) { if (isDev) {

13
src/utils/index.ts Normal file
View File

@@ -0,0 +1,13 @@
export * from './cluster.util'
export * from './consola.util'
export * from './crud.util'
export * from './dayjs.util'
export * from './ip.util'
export * from './nest.util'
export * from './pic.util'
export * from './query.util'
export * from './redis.util'
export * from './system.util'
export * from './time.util'
export * from './tool.util'
export * from './transfrom.util'

View File

@@ -1,6 +1,5 @@
import { isObject } from 'lodash' import { isObject } from 'lodash'
export * from './ip.util'
export const isDev = process.env.NODE_ENV == 'development' export const isDev = process.env.NODE_ENV == 'development'
export const isTest = !!process.env.TEST export const isTest = !!process.env.TEST

View File

@@ -1,4 +1,4 @@
import { sleep } from '~/utils/index.util' import { sleep } from '~/utils'
import { pickImagesFromMarkdown } from '~/utils/pic.util' import { pickImagesFromMarkdown } from '~/utils/pic.util'
describe('src/utils/pic.util', () => { describe('src/utils/pic.util', () => {