chunk() never resets its size counter: past 500 KB every queued event is uploaded as its own request
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 75/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- react-native, typescript
調査の方向性
バグは packages/core/src/util.ts 内の chunk 関数にあります。まず、関数と sizeOf ヘルパーを読んでください。この issue には再現ケースと提案された修正が含まれています。修正をテストするには、チャンキングロジックの既存のテストを実行するか、修正された動作が数千ではなく期待される20個のチャンクを返すことを確認する小さなテストを作成してください。リポジトリ内に関連するテストがないか確認してください。
索引モデルが issue の本文から書いたものです。
説明
Summary
chunk() in packages/core/src/util.ts never resets rollingKBSize. Once the queue's running size reaches maxKB (MAX_PAYLOAD_SIZE_IN_KB = 500), every later event goes into its own chunk. SegmentDestination.sendEvents then uploads all chunks at once with Promise.all, so a single flush sends one HTTP request per queued event.
if (maxKB !== undefined) {
rollingKBSize += sizeOf(item);
if (rollingKBSize >= maxKB) {
chunks[++currentChunk] = [item]; // rollingKBSize is never reset
return chunks;
}
}
Reproduction
chunk(events, 1000, 500) with 10,000 events of about 1 KB each returns 9,481 chunks: one of 520 events, then 9,480 of one event each. The expected result is 20 chunks of about 520.
Impact
It shows up when the queue grows past 500 KB, which happens when uploads keep failing (for example, a device whose DNS blocks *.segmentapis.com). The queue persists across launches. If cdn-settings.segment.com is unreachable too, there's no httpConfig, so no backoff and no maxTotalBackoffDuration pruning, and maxQueueSize isn't enforced anywhere. In production we saw one iOS session make about 9,700 upload attempts in 91 seconds, at a steady ~60 per second (URLSession's 6 connections per host).
Version: 2.24.1. Same code on master.
Suggested fix
Keep a size counter per chunk and reset it when a new chunk starts, and push chunks instead of assigning by index. That also fixes the sparse-array case in #1309.
export const chunk = <T>(array: T[], count: number, maxKB?: number): T[][] => {
if (!array.length || !count) return [];
const result: T[][] = [];
let current: T[] = [];
let currentKB = 0;
for (const item of array) {
const itemKB = maxKB !== undefined ? sizeOf(item) : 0;
const isFull = current.length >= count || (maxKB !== undefined && currentKB + itemKB >= maxKB);
if (current.length > 0 && isFull) {
result.push(current);
current = [];
currentKB = 0;
}
current.push(item);
currentKB += itemKB;
}
if (current.length > 0) result.push(current);
return result;
};
- 主要言語
- TypeScript
- スター
- 383
- フォーク
- 206
- 平均マージ
- 14時間 45分
- マージ済み PR(30日)
- 11
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
segmentio/analytics-react-native のほかの issue
-
bug investigate
難易度 1/5 1時間未満 初心者へのやさしさ 72/100
segmentio/analytics-react-native#1145 ·
-
enhancement
難易度 4/5 3〜5日 初心者へのやさしさ 68/100
segmentio/analytics-react-native#1328 ·
-
bug investigate
難易度 3/5 1〜2日 初心者へのやさしさ 78/100
segmentio/analytics-react-native#1309 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
segmentio/analytics-react-native#1124 · コメント 3 件 ·
-
enhancement
難易度 3/5 1〜2日 初心者へのやさしさ 48/100
segmentio/analytics-react-native#1114 ·
segmentio/analytics-react-native の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
bcgov/bc-wallet-mobile#4761 · コメント 1 件 ·
-
external-issue to-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
-
area-deployment area-integrations triage:bot-seen
難易度 2/5 半日 初心者へのやさしさ 86/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
refactor
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100