remove redis dep from deps.ts and move to redisCache.ts
This commit is contained in:
parent
4462d7d832
commit
62b2aa07de
4 changed files with 106 additions and 109 deletions
5
deps.ts
5
deps.ts
|
@ -2,11 +2,6 @@ export { EventEmitter } from 'https://deno.land/x/event@0.2.1/mod.ts'
|
|||
export { unzlib } from 'https://denopkg.com/DjDeveloperr/denoflate@1.2/mod.ts'
|
||||
export { fetchAuto } from 'https://deno.land/x/fetchbase64@1.0.0/mod.ts'
|
||||
export { parse } from 'https://deno.land/x/mutil@0.1.2/mod.ts'
|
||||
export { connect } from 'https://deno.land/x/redis@v0.14.1/mod.ts'
|
||||
export type {
|
||||
Redis,
|
||||
RedisConnectOptions
|
||||
} from 'https://deno.land/x/redis@v0.14.1/mod.ts'
|
||||
export { walk } from 'https://deno.land/std@0.86.0/fs/walk.ts'
|
||||
export { join } from 'https://deno.land/std@0.86.0/path/mod.ts'
|
||||
export { Mixin } from 'https://esm.sh/ts-mixer@5.4.0'
|
||||
|
|
1
mod.ts
1
mod.ts
|
@ -166,3 +166,4 @@ export type { VoiceStatePayload } from './src/types/voice.ts'
|
|||
export type { WebhookPayload } from './src/types/webhook.ts'
|
||||
export * from './src/models/collectors.ts'
|
||||
export type { Dict } from './src/utils/dict.ts'
|
||||
export * from './src/models/redisCache.ts'
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Collection } from '../utils/collection.ts'
|
||||
import { connect, Redis, RedisConnectOptions } from '../../deps.ts'
|
||||
|
||||
/**
|
||||
* ICacheAdapter is the interface to be implemented by Cache Adapters for them to be usable with Harmony.
|
||||
|
@ -71,106 +70,3 @@ export class DefaultCacheAdapter implements ICacheAdapter {
|
|||
return delete this.data[cacheName]
|
||||
}
|
||||
}
|
||||
|
||||
/** Redis Cache Adapter for using Redis as a cache-provider. */
|
||||
export class RedisCacheAdapter implements ICacheAdapter {
|
||||
_redis: Promise<Redis>
|
||||
redis?: Redis
|
||||
ready: boolean = false
|
||||
readonly _expireIntervalTimer: number = 5000
|
||||
private _expireInterval?: number
|
||||
|
||||
constructor(options: RedisConnectOptions) {
|
||||
this._redis = connect(options)
|
||||
this._redis.then(
|
||||
(redis) => {
|
||||
this.redis = redis
|
||||
this.ready = true
|
||||
this._startExpireInterval()
|
||||
},
|
||||
() => {
|
||||
// TODO: Make error for this
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private _startExpireInterval(): void {
|
||||
this._expireInterval = setInterval(() => {
|
||||
this.redis?.scan(0, { pattern: '*:expires' }).then(([_, names]) => {
|
||||
for (const name of names) {
|
||||
this.redis?.hvals(name).then((vals) => {
|
||||
for (const val of vals) {
|
||||
const expireVal: {
|
||||
name: string
|
||||
key: string
|
||||
at: number
|
||||
} = JSON.parse(val)
|
||||
const expired = new Date().getTime() > expireVal.at
|
||||
if (expired) this.redis?.hdel(expireVal.name, expireVal.key)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}, this._expireIntervalTimer)
|
||||
}
|
||||
|
||||
async _checkReady(): Promise<void> {
|
||||
if (!this.ready) await this._redis
|
||||
}
|
||||
|
||||
async get(cacheName: string, key: string): Promise<string | undefined> {
|
||||
await this._checkReady()
|
||||
const cache = await this.redis?.hget(cacheName, key)
|
||||
if (cache === undefined) return
|
||||
try {
|
||||
return JSON.parse(cache)
|
||||
} catch (e) {
|
||||
return cache
|
||||
}
|
||||
}
|
||||
|
||||
async set(
|
||||
cacheName: string,
|
||||
key: string,
|
||||
value: any,
|
||||
expire?: number
|
||||
): Promise<number | undefined> {
|
||||
await this._checkReady()
|
||||
const result = await this.redis?.hset(
|
||||
cacheName,
|
||||
key,
|
||||
typeof value === 'object' ? JSON.stringify(value) : value
|
||||
)
|
||||
if (expire !== undefined) {
|
||||
await this.redis?.hset(
|
||||
`${cacheName}:expires`,
|
||||
key,
|
||||
JSON.stringify({
|
||||
name: cacheName,
|
||||
key,
|
||||
at: new Date().getTime() + expire
|
||||
})
|
||||
)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
async delete(cacheName: string, key: string): Promise<boolean> {
|
||||
await this._checkReady()
|
||||
const exists = await this.redis?.hexists(cacheName, key)
|
||||
if (exists === 0) return false
|
||||
await this.redis?.hdel(cacheName, key)
|
||||
return true
|
||||
}
|
||||
|
||||
async array(cacheName: string): Promise<any[] | undefined> {
|
||||
await this._checkReady()
|
||||
const data = await this.redis?.hvals(cacheName)
|
||||
return data?.map((e: string) => JSON.parse(e))
|
||||
}
|
||||
|
||||
async deleteCache(cacheName: string): Promise<boolean> {
|
||||
await this._checkReady()
|
||||
return (await this.redis?.del(cacheName)) !== 0
|
||||
}
|
||||
}
|
||||
|
|
105
src/models/redisCache.ts
Normal file
105
src/models/redisCache.ts
Normal file
|
@ -0,0 +1,105 @@
|
|||
import { ICacheAdapter } from './cacheAdapter.ts'
|
||||
import { connect, Redis, RedisConnectOptions } from 'https://deno.land/x/redis@v0.14.1/mod.ts'
|
||||
|
||||
/** Redis Cache Adapter for using Redis as a cache-provider. */
|
||||
export class RedisCacheAdapter implements ICacheAdapter {
|
||||
_redis: Promise<Redis>
|
||||
redis?: Redis
|
||||
ready: boolean = false
|
||||
readonly _expireIntervalTimer: number = 5000
|
||||
private _expireInterval?: number
|
||||
|
||||
constructor(options: RedisConnectOptions) {
|
||||
this._redis = connect(options)
|
||||
this._redis.then(
|
||||
(redis) => {
|
||||
this.redis = redis
|
||||
this.ready = true
|
||||
this._startExpireInterval()
|
||||
},
|
||||
() => {
|
||||
// TODO: Make error for this
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private _startExpireInterval(): void {
|
||||
this._expireInterval = setInterval(() => {
|
||||
this.redis?.scan(0, { pattern: '*:expires' }).then(([_, names]) => {
|
||||
for (const name of names) {
|
||||
this.redis?.hvals(name).then((vals) => {
|
||||
for (const val of vals) {
|
||||
const expireVal: {
|
||||
name: string
|
||||
key: string
|
||||
at: number
|
||||
} = JSON.parse(val)
|
||||
const expired = new Date().getTime() > expireVal.at
|
||||
if (expired) this.redis?.hdel(expireVal.name, expireVal.key)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}, this._expireIntervalTimer)
|
||||
}
|
||||
|
||||
async _checkReady(): Promise<void> {
|
||||
if (!this.ready) await this._redis
|
||||
}
|
||||
|
||||
async get(cacheName: string, key: string): Promise<string | undefined> {
|
||||
await this._checkReady()
|
||||
const cache = await this.redis?.hget(cacheName, key)
|
||||
if (cache === undefined) return
|
||||
try {
|
||||
return JSON.parse(cache)
|
||||
} catch (e) {
|
||||
return cache
|
||||
}
|
||||
}
|
||||
|
||||
async set(
|
||||
cacheName: string,
|
||||
key: string,
|
||||
value: any,
|
||||
expire?: number
|
||||
): Promise<number | undefined> {
|
||||
await this._checkReady()
|
||||
const result = await this.redis?.hset(
|
||||
cacheName,
|
||||
key,
|
||||
typeof value === 'object' ? JSON.stringify(value) : value
|
||||
)
|
||||
if (expire !== undefined) {
|
||||
await this.redis?.hset(
|
||||
`${cacheName}:expires`,
|
||||
key,
|
||||
JSON.stringify({
|
||||
name: cacheName,
|
||||
key,
|
||||
at: new Date().getTime() + expire
|
||||
})
|
||||
)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
async delete(cacheName: string, key: string): Promise<boolean> {
|
||||
await this._checkReady()
|
||||
const exists = await this.redis?.hexists(cacheName, key)
|
||||
if (exists === 0) return false
|
||||
await this.redis?.hdel(cacheName, key)
|
||||
return true
|
||||
}
|
||||
|
||||
async array(cacheName: string): Promise<any[] | undefined> {
|
||||
await this._checkReady()
|
||||
const data = await this.redis?.hvals(cacheName)
|
||||
return data?.map((e: string) => JSON.parse(e))
|
||||
}
|
||||
|
||||
async deleteCache(cacheName: string): Promise<boolean> {
|
||||
await this._checkReady()
|
||||
return (await this.redis?.del(cacheName)) !== 0
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue