Skip to content

Commit 7602880

Browse files
Tolerblancsummersummerwhyezcolin2
committed
chore: websocket app 의존성 추가
Co-authored-by: Summer Min <[email protected]> Co-authored-by: ez <[email protected]>
1 parent 05f9e30 commit 7602880

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Module, forwardRef } from '@nestjs/common';
2+
import Redis from 'ioredis';
3+
import Redlock from 'redlock';
4+
import { RedisModule } from '../redis/redis.module';
5+
const RED_LOCK_TOKEN = 'RED_LOCK';
6+
const REDIS_CLIENT_TOKEN = 'REDIS_CLIENT';
7+
8+
@Module({
9+
imports: [forwardRef(() => RedisModule)],
10+
providers: [
11+
{
12+
provide: RED_LOCK_TOKEN,
13+
useFactory: (redisClient: Redis) => {
14+
return new Redlock([redisClient], {
15+
driftFactor: 0.01,
16+
retryCount: 10,
17+
retryDelay: 200,
18+
retryJitter: 200,
19+
automaticExtensionThreshold: 500,
20+
});
21+
},
22+
inject: [REDIS_CLIENT_TOKEN],
23+
},
24+
],
25+
exports: [RED_LOCK_TOKEN],
26+
})
27+
export class RedLockModule {}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Module, forwardRef } from '@nestjs/common';
2+
import { ConfigModule, ConfigService } from '@nestjs/config';
3+
import { RedisService } from './redis.service';
4+
import Redis from 'ioredis';
5+
import { RedLockModule } from '../red-lock/red-lock.module';
6+
7+
// 의존성 주입할 때 redis client를 식별할 토큰
8+
const REDIS_CLIENT_TOKEN = 'REDIS_CLIENT';
9+
10+
@Module({
11+
imports: [ConfigModule, forwardRef(() => RedLockModule)], // ConfigModule 추가
12+
providers: [
13+
RedisService,
14+
{
15+
provide: REDIS_CLIENT_TOKEN,
16+
inject: [ConfigService], // ConfigService 주입
17+
useFactory: (configService: ConfigService) => {
18+
return new Redis({
19+
host: configService.get<string>('REDIS_HOST'),
20+
port: configService.get<number>('REDIS_PORT'),
21+
});
22+
},
23+
},
24+
],
25+
exports: [RedisService, REDIS_CLIENT_TOKEN],
26+
})
27+
export class RedisModule {}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { Inject } from '@nestjs/common';
3+
import Redis from 'ioredis';
4+
import Redlock from 'redlock';
5+
const REDIS_CLIENT_TOKEN = 'REDIS_CLIENT';
6+
const RED_LOCK_TOKEN = 'RED_LOCK';
7+
8+
type RedisPage = {
9+
title?: string;
10+
content?: string;
11+
};
12+
13+
@Injectable()
14+
export class RedisService {
15+
constructor(
16+
@Inject(REDIS_CLIENT_TOKEN) private readonly redisClient: Redis,
17+
@Inject(RED_LOCK_TOKEN) private readonly redisLock: Redlock,
18+
) {}
19+
20+
async getAllKeys(pattern) {
21+
return await this.redisClient.keys(pattern);
22+
}
23+
24+
createStream() {
25+
return this.redisClient.scanStream();
26+
}
27+
28+
async get(key: string) {
29+
const data = await this.redisClient.hgetall(key);
30+
return Object.fromEntries(
31+
Object.entries(data).map(([field, value]) => [field, value]),
32+
) as RedisPage;
33+
}
34+
35+
async set(key: string, value: object) {
36+
// 락을 획득할 때까지 기다린다.
37+
const lock = await this.redisLock.acquire([`user:${key}`], 1000);
38+
try {
39+
await this.redisClient.hset(key, Object.entries(value));
40+
} finally {
41+
lock.release();
42+
}
43+
}
44+
45+
async setField(key: string, field: string, value: string) {
46+
// 락을 획득할 때까지 기다린다.
47+
const lock = await this.redisLock.acquire([`user:${key}`], 1000);
48+
try {
49+
return await this.redisClient.hset(key, field, value);
50+
} finally {
51+
lock.release();
52+
}
53+
}
54+
55+
async delete(key: string) {
56+
// 락을 획득할 때까지 기다린다.
57+
const lock = await this.redisLock.acquire([`user:${key}`], 1000);
58+
try {
59+
return await this.redisClient.del(key);
60+
} finally {
61+
lock.release();
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)