diff --git a/.github/workflows/build-and-push-bsky-aws.yaml b/.github/workflows/build-and-push-bsky-aws.yaml index 36b1aa23cb3..d2f836cfeda 100644 --- a/.github/workflows/build-and-push-bsky-aws.yaml +++ b/.github/workflows/build-and-push-bsky-aws.yaml @@ -3,6 +3,7 @@ on: push: branches: - main + - cache-tweaks env: REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }} USERNAME: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_USERNAME }} diff --git a/packages/bsky/src/cache/read-through.ts b/packages/bsky/src/cache/read-through.ts index b414026e086..ce63860c74d 100644 --- a/packages/bsky/src/cache/read-through.ts +++ b/packages/bsky/src/cache/read-through.ts @@ -17,13 +17,18 @@ export class ReadThroughCache { constructor(public redis: Redis, public opts: CacheOptions) {} private async _fetchMany(keys: string[]): Promise> { + let result: Record = {} if (this.opts.fetchManyMethod) { - return this.opts.fetchManyMethod(keys) + result = await this.opts.fetchManyMethod(keys) + } else { + const got = await Promise.all(keys.map((k) => this.opts.fetchMethod(k))) + for (let i = 0; i < keys.length; i++) { + result[keys[i]] = got[i] ?? null + } } - const got = await Promise.all(keys.map((k) => this.opts.fetchMethod(k))) - const result: Record = {} - for (let i = 0; i < keys.length; i++) { - result[keys[i]] = got[i] ?? null + // ensure caching negatives + for (const key of keys) { + result[key] ??= null } return result } diff --git a/packages/bsky/src/services/label/index.ts b/packages/bsky/src/services/label/index.ts index ed6691c09d0..e5748c8e38e 100644 --- a/packages/bsky/src/services/label/index.ts +++ b/packages/bsky/src/services/label/index.ts @@ -23,7 +23,7 @@ export class LabelService { ...cacheOpts, fetchMethod: async (subject: string) => { const res = await fetchLabelsForSubjects(db, [subject]) - return res[subject] ?? null + return res[subject] ?? [] }, fetchManyMethod: (subjects: string[]) => fetchLabelsForSubjects(db, subjects), @@ -200,7 +200,7 @@ const fetchLabelsForSubjects = async ( .where('label.uri', 'in', subjects) .selectAll() .execute() - return res.reduce((acc, cur) => { + const labelMap = res.reduce((acc, cur) => { acc[cur.uri] ??= [] acc[cur.uri].push({ ...cur, @@ -209,4 +209,9 @@ const fetchLabelsForSubjects = async ( }) return acc }, {} as Record) + // ensure we cache negatives + for (const subject of subjects) { + labelMap[subject] ??= [] + } + return labelMap }