You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

88 lines
1.8 KiB

import Redis from 'ioredis'
import type { CacheDriver } from '../types'
export interface RedisDriverOptions {
host: string
port: number
password?: string
db?: number
}
export class RedisDriver implements CacheDriver {
name = 'redis'
private redis: Redis
constructor(options: RedisDriverOptions) {
this.redis = new Redis({
host: options.host,
port: options.port,
password: options.password,
db: options.db ?? 0,
lazyConnect: true,
})
}
private serialize<T>(value: T): string {
return JSON.stringify(value)
}
private deserialize<T>(data: string): T {
try {
return JSON.parse(data) as T
} catch {
throw new Error(`[cache] Failed to deserialize data: ${data.substring(0, 100)}`)
}
}
async get<T>(key: string): Promise<T | null> {
try {
const data = await this.redis.get(key)
if (!data) return null
return this.deserialize<T>(data)
} catch (err) {
throw err
}
}
async set<T>(key: string, value: T, ttl = 0): Promise<void> {
try {
const serialized = this.serialize(value)
if (ttl > 0) {
await this.redis.set(key, serialized, 'EX', ttl)
} else {
await this.redis.set(key, serialized)
}
} catch (err) {
throw err
}
}
async del(key: string): Promise<void> {
try {
await this.redis.del(key)
} catch (err) {
throw err
}
}
async exists(key: string): Promise<boolean> {
try {
const result = await this.redis.exists(key)
return result === 1
} catch (err) {
throw err
}
}
async clear(): Promise<void> {
try {
await this.redis.flushdb()
} catch (err) {
throw err
}
}
async disconnect(): Promise<void> {
await this.redis.quit()
}
}