Skip to content

Commit

Permalink
hotfix/async module
Browse files Browse the repository at this point in the history
  • Loading branch information
choewy committed Mar 23, 2024
1 parent 692752d commit 10ff886
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 24 deletions.
21 changes: 15 additions & 6 deletions libs/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { Module, OnApplicationBootstrap } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';

import { REDIS_CONFIG, RedisConfig } from './redis.config';
import { OnRedisPub, RedisPubPayloadParam } from '../decorators';
import { RedisPubPayload } from '../implements';
import { RedisModule } from '../redis.module';
import { RedisPub } from '../redis.pub';

@Module({
imports: [
RedisModule.register({
host: 'localhost',
port: 6380,
db: 0,
pub: { use: true },
sub: { use: true, channels: ['welcome'] },
ConfigModule.forRoot({
isGlobal: true,
load: [RedisConfig],
}),
RedisModule.forRootAsync({
inject: [ConfigService],
useFactory(configService: ConfigService) {
return {
...configService.get(REDIS_CONFIG),
pub: { use: true },
sub: { use: true, channels: ['welcome'] },
};
},
}),
],
})
Expand Down
12 changes: 12 additions & 0 deletions libs/app/redis.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { registerAs } from '@nestjs/config';
import { RedisModuleOptions } from 'libs/interfaces';

export const REDIS_CONFIG = '__REDIS_CONFIG__';
export const RedisConfig = registerAs(
REDIS_CONFIG,
(): RedisModuleOptions => ({
host: 'localhost',
port: 6380,
db: 0,
}),
);
1 change: 0 additions & 1 deletion libs/interfaces/redis-module-options.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { RedisPubOptions } from './redis-pub-options.interface';
import { RedisSubOptions } from './redis-sub-options.interface';

export interface RedisModuleOptions extends RedisOptions {
global?: boolean;
pub?: RedisPubOptions;
sub?: RedisSubOptions;
}
Expand Down
65 changes: 48 additions & 17 deletions libs/redis.module.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { DynamicModule, Module, Provider, Type } from '@nestjs/common';
import { EventEmitterModule, EventEmitter2 } from '@nestjs/event-emitter';
import { Redis, RedisOptions } from 'ioredis';
import { Redis } from 'ioredis';

import { RedisModuleAsyncOptions, RedisModuleOptions, RedisPubOptions, RedisSubOptions } from './interfaces';
import { RedisModuleAsyncOptions, RedisModuleOptions } from './interfaces';
import { RedisPub } from './redis.pub';
import { RedisSub } from './redis.sub';

@Module({})
export class RedisModule {
private static createProviders(redisOptions: RedisOptions, pubOptions?: RedisPubOptions, subOptions?: RedisSubOptions) {
static forRoot({ pub, sub, ...redisOptions }: RedisModuleOptions): DynamicModule {
const providers: Array<Type<any> | Provider> = [
{
provide: Redis,
Expand All @@ -18,44 +18,75 @@ export class RedisModule {
},
];

if (pubOptions?.use) {
if (pub?.use) {
providers.push({
inject: [Redis],
provide: RedisPub,
useFactory(redis: Redis) {
return new RedisPub(redis.duplicate(), pubOptions);
return new RedisPub(redis.duplicate(), pub);
},
});
}

if (subOptions?.use) {
if (sub?.use) {
providers.push({
inject: [Redis, EventEmitter2],
provide: RedisSub,
useFactory(redis: Redis, eventEmitter: EventEmitter2) {
return new RedisSub(redis.duplicate(), subOptions, eventEmitter);
return new RedisSub(redis.duplicate(), sub, eventEmitter);
},
});
}

return providers;
}

private static createDynamicModule(providers: Array<Provider | Type<any>>, global?: boolean): DynamicModule {
return {
global,
global: true,
module: RedisModule,
imports: [EventEmitterModule.forRoot({ global: false })],
providers,
exports: providers,
};
}

static register({ global, pub, sub, ...redisOptions }: RedisModuleOptions): DynamicModule {
return this.createDynamicModule(this.createProviders(redisOptions, pub, sub), global);
}
static async forRootAsync(moduleAsyncOptions: RedisModuleAsyncOptions) {
const providers: Array<Type<any> | Provider> = [
{
provide: Redis,
inject: moduleAsyncOptions.inject,
async useFactory(...dependencies) {
const options = await moduleAsyncOptions.useFactory(...dependencies);
return new Redis(options);
},
},
{
provide: RedisPub,
inject: [Redis, ...moduleAsyncOptions.inject],
async useFactory(redis, ...dependencies) {
const options = await moduleAsyncOptions.useFactory(...dependencies);

static async registerAsync(moduleAsyncOptions: RedisModuleAsyncOptions) {
return this.register(await moduleAsyncOptions.useFactory(...moduleAsyncOptions.inject));
if (options.pub?.use) {
return new RedisPub(redis, options.pub);
}
},
},
{
provide: RedisSub,
inject: [Redis, EventEmitter2, ...moduleAsyncOptions.inject],
async useFactory(redis: Redis, eventEmitter, ...dependencies) {
const options = await moduleAsyncOptions.useFactory(...dependencies);

if (options.sub?.use) {
return new RedisSub(redis.duplicate(), options.sub, eventEmitter);
}
},
},
];

return {
global: true,
module: RedisModule,
imports: [EventEmitterModule.forRoot({ global: false })],
providers,
exports: providers,
};
}
}
57 changes: 57 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"reflect-metadata": "^0.2.1"
},
"devDependencies": {
"@nestjs/config": "^3.2.0",
"@nestjs/core": "^10.3.3",
"@nestjs/platform-express": "^10.3.3",
"@typescript-eslint/eslint-plugin": "^7.2.0",
Expand Down

0 comments on commit 10ff886

Please sign in to comment.