Failed batch evicts a replacement cache entry after clear/prime
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 57/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- javascript, node.js
調査の方向性
Start by reading failedDispatch() in the current source, then inspect the cache handling and tests for failed batches, clear() and prime(). Use the manual scheduler reproduction in the issue to confirm that an old rejection preserves a replacement cache entry while still allowing failed requests to retry. Done means the reproduction passes and custom cache maps, duplicate keys across batches, and normalized cache keys behave as described.
索引モデルが issue の本文から書いたものです。
説明
Expected Behavior
If a pending load is cleared and replaced with prime() (or another load()), failure of the old batch should reject its own requests without evicting the replacement cache entry. A failed request should still be evicted when the cache contains that request's promise, so subsequent loads can retry.
Current Behavior
With dataloader 2.2.3 on Node v22.23.1, an old batch failure clears the replacement entry. The reproduction below returns backend:a and makes two backend calls, instead of returning replacement with one backend call.
The same unconditional clear is present in failedDispatch() on current main, commit 65be452f5ffad3eede2d862dc26c96003fa87ef3. I inspected that source; the reproduction was run against the published 2.2.3 package.
Possible Solution
Retain the cache-promise identity associated with each queued request and only evict it if the current entry for the normalized cache key still belongs to that request. The batch's own rejection should remain unchanged. This needs to preserve ordinary failed-batch retries, custom cache maps, and duplicate keys across batches.
Steps to Reproduce
Install [email protected] and run this script with Node. It uses a manual batch scheduler and a controlled rejection, with no timing delays:
const assert = require('node:assert/strict');
const DataLoader = require('dataloader');
(async () => {
let rejectOld;
const firstBatch = new Promise((_, reject) => { rejectOld = reject; });
let dispatch;
let batches = 0;
const loader = new DataLoader(keys => {
batches++;
return batches === 1 ? firstBatch : Promise.resolve(keys.map(k => `backend:${k}`));
}, { batchScheduleFn: fn => { dispatch = fn; } });
const old = loader.load('a').catch(error => error.message);
dispatch();
loader.clear('a').prime('a', 'replacement');
rejectOld(new Error('old batch failed'));
assert.equal(await old, 'old batch failed');
const next = loader.load('a');
dispatch();
const value = await next;
console.log({ value, batches }); // { value: 'backend:a', batches: 2 }
assert.equal(value, 'replacement'); // Fails on 2.2.3.
assert.equal(batches, 1);
})().catch(error => { console.error(error); process.exitCode = 1; });
Context
This was also reproduced in the Python port: https://github.com/syrusakbary/aiodataloader/issues/59, with a proposed fix at https://github.com/syrusakbary/aiodataloader/pull/60. Its maintainer requested an upstream report because the port aims to mirror DataLoader's behavior. The Python PR is still open; this report does not assume that its implementation can be copied directly to JavaScript.
Additional local diagnostics reproduce the eviction after a replacement load has completed (an unnecessary third backend batch), and with a normalized cache key. Controls with a successful old batch or a different primed key retain the replacement. This changes observable cache behavior, so the release/compatibility implications should be considered alongside the fix.
- 主要言語
- JavaScript
- スター
- 13.4k
- フォーク
- 522
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
graphql/dataloader のほかの issue
-
[BUG] `maxBatchSize: NaN` is accepted and silently disables batching対応中かも @RaphaelFakhri が 2 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
graphql/dataloader#405 ·
-
enhancement
難易度 5/5 1週間以上 初心者へのやさしさ 38/100
graphql/dataloader#393 ·
-
enhancement
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
graphql/dataloader#382 ·
-
enhancement
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
graphql/dataloader#379 · コメント 2 件 · リアクション 5 件 ·
-
bug
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
graphql/dataloader#377 · コメント 1 件 · リアクション 1 件 ·
graphql/dataloader の issue をすべて見る
似ている issue
-
bug needs-triage potential-regression
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
aws/aws-sdk-js-v3#8408 ·
メンテナーはふだん 1 日以内に返信
-
[v3] KeyBindingManager calls (Add/Remove) are not converted into a case-insensitive accelerator.KeyオープンBug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 4 日以内に返信
-
fix(docs): align git__gh troubleshooting with its actual failure paths対応中かも @akhil9tiet が今日担当しました。 オープンbug docs p2
難易度 1/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100