From 300f0736385ceeb6fb270275208367b1bc5ad63c Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Wed, 20 May 2026 17:12:16 +0700 Subject: [PATCH] fixed bug Redis Client Connection Leak --- src/controllers/AuthRoleController.ts | 48 ++++++---- src/controllers/PermissionController.ts | 119 +++++++++++++++++------- 2 files changed, 115 insertions(+), 52 deletions(-) diff --git a/src/controllers/AuthRoleController.ts b/src/controllers/AuthRoleController.ts index 4159c5ec..2e51a79d 100644 --- a/src/controllers/AuthRoleController.ts +++ b/src/controllers/AuthRoleController.ts @@ -123,18 +123,25 @@ export class AuthRoleController extends Controller { // เช็คว่าถ้ามีค่า current_holderId ให้ลบ key สิทธิ์ใน redis if (posMaster.current_holderId) { - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); - redisClient.del("role_" + posMaster.current_holderId, (err: Error, response: Response) => { - if (err) throw err; - }); + redisClient.del("role_" + posMaster.current_holderId, (err: Error, response: Response) => { + if (err) throw err; + }); - redisClient.del("menu_" + posMaster.current_holderId, (err: Error, response: Response) => { - if (err) throw err; - }); + redisClient.del("menu_" + posMaster.current_holderId, (err: Error, response: Response) => { + if (err) throw err; + }); + } finally { + if (redisClient) { + redisClient.quit(); + } + } } return new HttpSuccess(); @@ -266,14 +273,21 @@ export class AuthRoleController extends Controller { ...newAttrs.map((attr) => this.authRoleAttrRepo.save(attr)), ]); - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); - await redisClient.flushdb(function (err: any, succeeded: any) { - console.log(succeeded); // will be true if successfull - }); + await redisClient.flushdb(function (err: any, succeeded: any) { + console.log(succeeded); // will be true if successfull + }); + } finally { + if (redisClient) { + redisClient.quit(); + } + } return new HttpSuccess(); } diff --git a/src/controllers/PermissionController.ts b/src/controllers/PermissionController.ts index 8c713947..44747b09 100644 --- a/src/controllers/PermissionController.ts +++ b/src/controllers/PermissionController.ts @@ -37,11 +37,13 @@ export class PermissionController extends Controller { @Get("") public async getPermission(@Request() request: RequestWithUser) { - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profile: any = await this.profileRepo.findOne({ select: ["id"], @@ -270,6 +272,11 @@ export class PermissionController extends Controller { redisClient.setex("role_" + profile.id, 86400, JSON.stringify(reply)); } return new HttpSuccess(reply); + } finally { + if (redisClient) { + redisClient.quit(); + } + } } @Get("menu") @@ -281,11 +288,13 @@ export class PermissionController extends Controller { orgRevisionIsCurrent: true, }, }); - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profileType = "OFFICER"; let profile: any = await this.profileRepo.findOne({ @@ -438,6 +447,11 @@ export class PermissionController extends Controller { } return new HttpSuccess(reply); + } finally { + if (redisClient) { + redisClient.quit(); + } + } } /** @@ -672,11 +686,13 @@ export class PermissionController extends Controller { @Path() system: string, @Path() action: string, ) { - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profileType = "OFFICER"; let profile: any = await this.profileRepo.findOne({ @@ -765,6 +781,11 @@ export class PermissionController extends Controller { } return new HttpSuccess(reply); + } finally { + if (redisClient) { + redisClient.quit(); + } + } } @Get("user/{system}/{action}/{id}") @@ -781,11 +802,13 @@ export class PermissionController extends Controller { orgRevisionIsCurrent: true, }, }); - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let org = this.PermissionOrg(request, system, action); let reply = await getAsync("user_" + id); @@ -866,14 +889,21 @@ export class PermissionController extends Controller { } return new HttpSuccess(reply); + } finally { + if (redisClient) { + redisClient.quit(); + } + } } public async getPermissionFunc(@Request() request: RequestWithUser) { - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profile: any = await this.profileRepo.findOne({ select: ["id"], @@ -1090,6 +1120,11 @@ export class PermissionController extends Controller { redisClient.setex("role_" + profile.id, 86400, JSON.stringify(reply)); } return reply; + } finally { + if (redisClient) { + redisClient.quit(); + } + } } public async Permission(req: RequestWithUser, system: string, action: string) { @@ -1115,11 +1150,13 @@ export class PermissionController extends Controller { } public async listAuthSysOrgFunc(request: RequestWithUser, system: string, action: string) { - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profileType = "OFFICER"; let profile: any = await this.profileRepo.findOne({ @@ -1187,6 +1224,11 @@ export class PermissionController extends Controller { redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply)); } return reply; + } finally { + if (redisClient) { + redisClient.quit(); + } + } } // Helper method: ดึง org scope จากตำแหน่งปกติ @@ -1366,11 +1408,13 @@ export class PermissionController extends Controller { @Get("checkOrg/{keycloakId}") public async checkOrg(@Path() keycloakId: string) { - const redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - // const getAsync = promisify(redisClient.get).bind(redisClient); + let redisClient; + try { + redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + // const getAsync = promisify(redisClient.get).bind(redisClient); // let profileType = "OFFICER"; let profile: any = await this.profileRepo.findOne({ @@ -1448,5 +1492,10 @@ export class PermissionController extends Controller { // } return new HttpSuccess(reply); + } finally { + if (redisClient) { + redisClient.quit(); + } + } } }