diff --git a/package-lock.json b/package-lock.json index 96c3533..8182a03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15843,6 +15843,7 @@ "@web3-storage/filecoin-api": "^7.2.0", "@web3-storage/filecoin-client": "^3.3.3", "fzstd": "^0.1.0", + "lru-cache": "^11.0.0", "multiformats": "12.0.1", "p-all": "^5.0.0", "p-retry": "^5.1.2", @@ -15948,6 +15949,14 @@ "npm": ">=7.0.0" } }, + "packages/core/node_modules/lru-cache": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", + "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "engines": { + "node": "20 || >=22" + } + }, "packages/core/node_modules/multiformats": { "version": "12.0.1", "license": "Apache-2.0 OR MIT", diff --git a/packages/core/package.json b/packages/core/package.json index b435d1f..ddfca67 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -26,6 +26,7 @@ "@web3-storage/filecoin-api": "^7.2.0", "@web3-storage/filecoin-client": "^3.3.3", "fzstd": "^0.1.0", + "lru-cache": "^11.0.0", "multiformats": "12.0.1", "p-all": "^5.0.0", "p-retry": "^5.1.2", diff --git a/packages/core/src/store/aggregator-buffer-store.js b/packages/core/src/store/aggregator-buffer-store.js index 45b994e..999445b 100644 --- a/packages/core/src/store/aggregator-buffer-store.js +++ b/packages/core/src/store/aggregator-buffer-store.js @@ -1,5 +1,6 @@ import { CBOR } from '@ucanto/core' import { parseLink } from '@ucanto/server' +import { LRUCache } from 'lru-cache' import { createBucketClient } from './bucket-client.js' @@ -67,3 +68,25 @@ export function createClient (conf, context) { decodeBucketResponse }) } + +const CACHE_MAX = 10_000 + +/** + * @param {import('@web3-storage/filecoin-api/aggregator/api').BufferStore} bufferStore + * @returns {import('@web3-storage/filecoin-api/aggregator/api').BufferStore} + */ +export const withCache = (bufferStore) => { + /** @type {LRUCache} */ + const cache = new LRUCache({ max: CACHE_MAX }) + return { + ...bufferStore, + async get (key) { + const cacheKey = key.toString() + const cached = cache.get(cacheKey) + if (cached) return { ok: cached } + const res = await bufferStore.get(key) + if (res.ok) cache.set(cacheKey, res.ok) + return res + } + } +} diff --git a/packages/functions/src/aggregator/handle-buffer-queue-message.js b/packages/functions/src/aggregator/handle-buffer-queue-message.js index 0559af8..14815d8 100644 --- a/packages/functions/src/aggregator/handle-buffer-queue-message.js +++ b/packages/functions/src/aggregator/handle-buffer-queue-message.js @@ -1,6 +1,6 @@ import * as Sentry from '@sentry/serverless' -import { createClient as createBufferStoreClient } from '@w3filecoin/core/src/store/aggregator-buffer-store.js' +import { createClient as createBufferStoreClient, withCache as withBufferStoreCache } from '@w3filecoin/core/src/store/aggregator-buffer-store.js' import { createClient as createBufferQueueClient, decodeMessage } from '@w3filecoin/core/src/queue/buffer-queue.js' import { createClient as createAggregateOfferQueueClient } from '@w3filecoin/core/src/queue/aggregate-offer-queue.js' import * as aggregatorEvents from '@web3-storage/filecoin-api/aggregator/events' @@ -83,9 +83,11 @@ function getContext () { } = getEnv() return { - bufferStore: createBufferStoreClient( - { region: bufferStoreBucketRegion }, - { name: bufferStoreBucketName } + bufferStore: withBufferStoreCache( + createBufferStoreClient( + { region: bufferStoreBucketRegion }, + { name: bufferStoreBucketName } + ) ), bufferQueue: createBufferQueueClient( { region: bufferQueueRegion },