chunk() never resets its size counter: past 500 KB every queued event is uploaded as its own request
还没有人认领这个 Issue。
评估
- 难度
- 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 分钟
- 30 天内合并 PR
- 11
环境准备
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 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
diegosouzapw/OmniRoute#14869 ·
维护者通常 1 天内回复
-
enhancement
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 94/100
维护者通常 1 天内回复
-
status: waiting triage
难度 2/5 1-3 小时 新手友好度 84/100
freeCodeCamp/freeCodeCamp#70412 ·
维护者通常 1 天内回复
-
Mend: dependency security vulnerability untriaged
难度 1/5 1 小时以内 新手友好度 88/100
opensearch-project/OpenSearch-Dashboards#12816 ·
维护者通常 1 天内回复