Skip to content

Commit

Permalink
build: add redis storage cache
Browse files Browse the repository at this point in the history
  • Loading branch information
cyberboyanmol committed Aug 27, 2024
1 parent b3fa32a commit 47658da
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 11 deletions.
5 changes: 2 additions & 3 deletions src/infra/redis/redis.client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { RedisClient } from './dal.redis'

// Creating Redis clients for different URLs
const redisdb = RedisClient.getInstance(process.env.EXERCISEDB_CACHE!, 'REDIS_DB')
const redisStorageCache = RedisClient.getInstance(process.env.EXERCISEDB_STORAGE_CACHE!, 'EXERCISEDB_STORAGE_CACHE')

export { redisdb }
export { redisStorageCache }
8 changes: 8 additions & 0 deletions src/infra/redis/redis.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ export class RedisService implements RedisRepositoryInterface {
async setWithExpiry(prefix: string, key: string, value: any, expiry: number): Promise<void> {
await this.redisClient.set(`${prefix}:${key}`, JSON.stringify(value), 'EX', expiry)
}
async getBuffer(prefix: string, key: string): Promise<Buffer | null> {
const value = await this.redisClient.getBuffer(`${prefix}:${key}`)
return value || null
}

async setBuffer(prefix: string, key: string, value: Buffer): Promise<void> {
await this.redisClient.set(`${prefix}:${key}`, value)
}
}
26 changes: 18 additions & 8 deletions src/modules/images/use-cases/view-image/view-image.usecase.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
import { IUseCase } from '#common/types/use-case.type.js'
import { redisStorageCache } from '#infra/redis/redis.client.js'
import { RedisService } from '#infra/redis/redis.service.js'
import axios, { AxiosResponse } from 'axios'
import { HTTPException } from 'hono/http-exception'

export class ViewImageUseCase implements IUseCase<string, any> {
constructor() {}
export class ViewImageUseCase implements IUseCase<string, Buffer> {
private readonly redisService: RedisService
constructor() {
this.redisService = new RedisService(redisStorageCache)
}

async execute(fileName: string): Promise<any> {
async execute(fileName: string): Promise<Buffer> {
const cacheKey = fileName.endsWith('.gif') ? fileName : `${fileName}.gif`
const sourceUrl = fileName.endsWith('.gif')
? `${process.env.SUPABASE_BUCKET_URL}/${process.env.SUPABASE_BUCKET_NAME}/${fileName}`
: `${process.env.SUPABASE_BUCKET_URL}/${process.env.SUPABASE_BUCKET_NAME}/${fileName}.gif`

try {
const cachedImage = await this.redisService.getBuffer('image', cacheKey)

if (cachedImage) {
return cachedImage
}
const response = await axios.get(sourceUrl, {
responseType: 'arraybuffer'
})

if (response.status === 404 || response.status === 400) {
if (response.status === 404 || response.status === 400 || response.status !== 200) {
throw new HTTPException(404, { message: 'Image not found or URL expired' })
}

if (response.status !== 200) {
throw new HTTPException(400, { message: 'Image not found or URL expired' })
}
const imageBuffer = response.data
await this.redisService.setBuffer('image', cacheKey, imageBuffer)

return response.data
return imageBuffer
} catch (error) {
if (axios.isAxiosError(error)) {
const statusCode = error.response?.status
Expand Down

0 comments on commit 47658da

Please sign in to comment.