让app.use()等待与Redis实例的连接建立

问题描述 投票:0回答:1

我正在编写一个依赖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连接?

node.js express redis node-redis
1个回答
0
投票

您可以在异步功能中设置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();
© www.soinside.com 2019 - 2024. All rights reserved.