我正在编写一个依赖redis存储的快速中间件功能,以启用速率限制。它有效,但是问题是我将Redis凭证存储在Google Cloud的秘密管理器中。我需要对secret-manager进行asynchronous请求,因此redis连接的状态会有很小的延迟。
我与redis实例连接的函数返回一个promise。兑现承诺后,便会建立redis连接。
'use strict'
// global variables for use in other functions as well
let globals = {}
// redis component where the connection with the redis instance is established
const Redis = require('./components/redis')
// connect is a promise
Redis.connect.then(conn => {
// connection established
globals.redis = conn
// globals.redis contains now the connection with the redis instance
// for use in other functions, this works
}).catch(err => console.log('could not connect with the redis instance')
// rate limiter function which depends on a redis instance
const RateLimiter = require('./components/rate-limiter')
const rateLimiter = RateLimiter({
store: globals.redis,
windowMs: 60 * 60 * 1000,
max: 5
})
app.use(rateLimiter)
此代码将不起作用,因为已执行app.use(ratelimiter)之前 redis连接已建立。移动RateLimiter代码inside redis promises的then()函数不会导致错误,但是app.use()函数则无法工作。
我理想的解决方案是:
// connect is a promise
Redis.connect.then(conn => {
// connection established
globals.redis = conn
// globals.redis contains now the connection with the redis instance
// for use in other functions, this works
// <-- MOVING THE RATE LIMITER CODE INSIDE THE THEN()-FUNCTION
// DOES NOT WORK / THE MIDDLEWARE IS NOT USED -->
// rate limiter function which depends on a redis instance
const RateLimiter = require('./components/rate-limiter')
const rateLimiter = RateLimiter({
store: globals.redis,
windowMs: 60 * 60 * 1000,
max: 5
})
app.use(rateLimiter)
}).catch(err => console.log('could not connect with the redis instance')
我如何让app.use()等待直到存在redis连接?
您可以在异步功能中设置redis并使用async / await,如下所示:
'use strict'
// global variables for use in other functions as well
let globals = {}
// redis component where the connection with the redis instance is established
const Redis = require('./components/redis')
async function setupRedis()
try {
// connect is a promise
const conn = await Redis.connect;
// connection established
globals.redis = conn
// globals.redis contains now the connection with the redis instance
// for use in other functions, this works
// rate limiter function which depends on a redis instance
const RateLimiter = require('./components/rate-limiter')
const rateLimiter = RateLimiter({
store: globals.redis,
windowMs: 60 * 60 * 1000,
max: 5
})
app.use(rateLimiter)
} catch (error) {
console.error("could not connect with the redis instance");
// rethrow error or whatever, just exit this function
}
setupRedis();