fix: worker event bus emit
This commit is contained in:
@@ -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)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
7
src/utils/cluster.util.ts
Normal file
7
src/utils/cluster.util.ts
Normal 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 })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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, {
|
||||||
|
|||||||
@@ -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
13
src/utils/index.ts
Normal 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'
|
||||||
@@ -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
|
||||||
@@ -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', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user