пусть app.use () подождет, пока не будет установлено соединение с экземпляром redis - PullRequest
0 голосов
/ 24 апреля 2020

Я пишу функцию промежуточного программного обеспечения express, которая зависит от хранилища Redis, чтобы включить ограничение скорости. Это работает, но проблема в том, что я храню свои учетные данные redis в секретном менеджере облака Google. Мне нужно сделать асинхронный запрос к secret-manager, чтобы была небольшая задержка состояния соединения redis.

Моя функция для соединения с экземпляром redis возвращает обещание. Когда обещание выполнено, соединение 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 внутри функции then () - обещаний redis не вызывает ошибку, но функция 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?

1 Ответ

0 голосов
/ 24 апреля 2020

Вы можете настроить redis в функции asyn c и использовать 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();
...