Эта проблема:
В настоящее время я использую socket.io
(на стороне сервера) для обработки асинхронных запросов от клиента. Эти запросы передаются вышестоящей службе, которая достаточно дорога / медленная и ограничена по скорости. Я хотел бы демультиплексировать / кэшировать вызовы вышестоящей службы. например 10x вызовов для getUserProfile(123)
=> 1x вызов восходящей службы (в течение периода времени)
Я пробовал использовать кеш (lru-cache), однако от клиента поступает ряд вызовов (в течение миллисекунд) до получения ответа от вышестоящего сервера (для первого вызова - так что это не работает).
Библиотека отговорка-обещание звучит как то, что мне нужно, однако она не принимает во внимание разные параметры (напримерgetUserProfile(123)
и getUserProfile(456)
=> ожидается profile_123
и profile_456
, но возвращает profile_456
(дважды).
Наверное, лучше всего, если я приведу пример ...
server.js
// on request from client...
socket.on('getUserProfileRequest', userId => {
getUserProfile(userId).then(profile => socket.emit('getUserProfileResponse', profile))
})
...
function getUserProfile(userId) {
// ... call upstream server, do async work, return a Promise...
}
Привет @barbsan - accumulate
не совсем то, что я пытаюсь захватить. Я хотел бы немедленно выполнить первый запрос, а затем кэшировать результат для других вызовов, используя те же параметры.
Я закончил тем, что использовал lru-cache
в сочетании с maxAge
и Promises
, чтобы достичь желаемого результата - я также добавил параметр initialiseFn
к функции get(key, initialiseFn)
, чтобы облегчить это.
PR:https://github.com/isaacs/node-lru-cache/pull/132
// setup an LRU cache (with eviction policy)...
const PROFILE_CACHE = LRU({ max: 50, maxAge: 1000 * 60 })
// receives "lots" of async requests from a client...
socket.on('getUserProfileRequest', userId => {
PROFILE_CACHE.get(userId, () => getUserProfile(userId))
.then(profile => socket.emit('getUserProfileResponse', profile))
})
// calls upstream server, does async/expensive/long running work, returns a Promise...
function getUserProfile(userId) { /* ... */ }
Объявление 2 .: Вы пробовали установить
accumulate
наtrue
, как в этот пример? Кажется, что без этого все вызовы используют один и тот же параметр.