Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: send data by chunk in websocket #3988

Merged
merged 21 commits into from
Feb 20, 2025
Merged

feat: send data by chunk in websocket #3988

merged 21 commits into from
Feb 20, 2025

Conversation

bytemain
Copy link
Member

@bytemain bytemain commented Sep 3, 2024

Types

  • 🎉 New Features

Background or solution

一次性发送几十M的文件会导致线程卡顿,大文件分 chunk 发送

Changelog

Summary by CodeRabbit

  • Refactor

    • 优化了组件树刷新和数组处理机制,提高加载及响应速度。
    • 改进了 WebSocket 连接的数据处理与消息传输逻辑,增强了异常处理和系统稳定性。
    • 优化了数据解码、缓冲区管理及切片方法,提升了大批量数据处理效率。
  • New Features

    • 引入了异步消息发送机制和队列管理,确保数据传输更顺畅。
    • 新增了缓冲区切片和读取方法,提高小数据块处理能力。
    • 增强了测试覆盖,确保缓冲区和游标的边界情况得到验证。
    • 新增了对 WebSocket 消息处理的类型安全支持。
    • 增加了对空缓冲区和边界情况的处理测试,确保方法的正确性。

Copy link
Contributor

coderabbitai bot commented Sep 3, 2024

Walkthrough

该 PR 修改涉及多个模块。
在 TreeNode 中优化了 spliceArray 函数和 hardReloadChildren 方法,提高了数组操作效率和子节点加载响应性。
在 Connection 模块中,对 WebSocket 连接、数据帧解码、消息发送及队列处理进行重构,实现了异步发送(返回 Promise)和更严格的错误管理。
同时,对 Buffers 类和 Cursor 类新增了针对小片段数据读取的功能,并在多个测试文件中增加了边界、并发和性能测试,提升了整体代码的健壮性和可维护性。

Changes

文件路径 变更摘要
packages/components/src/recycle-tree/tree/TreeNode.ts 优化 spliceArray 实现和 hardReloadChildren 方法:提前返回、预分配数组、利用事件循环让渡,提升性能。
packages/connection/__test__/browser/index.test.ts
packages/connection/src/common/connection/drivers/reconnecting-websocket.ts
packages/connection/src/common/connection/drivers/ws-websocket.ts
更新 WS WebSocket 连接管理:引入 WSWebSocketConnection,将 send 方法改为返回 Promise;增加消息队列处理(processSendQueue)及专用 arrayBufferHandler,改善消息监听和发送流程。
packages/connection/__test__/common/frame-decoder.test.ts
packages/connection/src/common/connection/drivers/frame-decoder.ts
修改数据帧解码逻辑:packet 构建方式改用 .dump(),采用 async/await 处理异步操作,并引入常量 MAX_ITERATIONSlengthFieldLength,加强错误处理。
packages/connection/src/common/buffers/buffers.ts
packages/connection/__test__/common/buffers.test.ts
为 Buffers 类新增常量 buffer4Capacityslice4 方法,以及 Cursor 的 read4 方法;测试增加了空缓冲、边界、跨块操作、游标移动、资源管理和大数据性能验证。
packages/connection/src/common/connection/drivers/stream.ts 改进 StreamConnection 的 send 方法,利用 dumpAndOwn() 构造数据,加上错误回调和 finally 释放资源。
packages/connection/src/common/constants.ts 新增常量 chunkSize(1MB),用于数据分片处理。
packages/connection/src/node/common-channel-handler.ts 简化 WebSocket 连接实例化,直接传入 WSWebSocketConnection,移除中间变量。
packages/core-browser/__tests__/bootstrap/connection.test.ts sleep 函数替换基于 Promise 的 setTimeout 延时,实现更直观的延迟效果。
packages/connection/__test__/node/index.test.ts
packages/connection/__test__/node/ws-channel.test.ts
更新 Node 测试:新增 ChannelMessage 引入,改用 wrappedConnection.onMessage 处理消息;调整消息内容(动态生成)及延长超时设置。
packages/connection/src/common/fury-extends/one-of.ts deserialize 方法中增加 default 分支,遇未知索引时抛出错误,增强错误检测与健壮性。

Sequence Diagram(s)

sequenceDiagram
    participant 客户端 as Client
    participant WSConn as WSWebSocketConnection
    participant Socket as WebSocket

    客户端->>WSConn: send(data)
    WSConn->>WSConn: 将 data 入队 (sendQueue)
    WSConn->>WSConn: 调用 processSendQueue() 处理队列
    WSConn->>Socket: 异步分片发送数据
    Socket-->>WSConn: 发送确认或错误反馈
    WSConn->>WSConn: 更新 pendingSize 及异常处理
    WSConn->>客户端: 返回 Promise resolve/reject
Loading
sequenceDiagram
    participant Socket as 数据流
    participant Decoder as LengthFieldBasedFrameDecoder
    participant 日志 as Logger

    Socket->>Decoder: push(data)
    Decoder->>Decoder: 异步执行 readFrame(),读取数据帧
    alt 解析成功
        Decoder-->>Socket: 返回完整数据帧
    else 解析失败
        Decoder->>日志: 记录错误信息
    end
Loading

Suggested reviewers

  • erha19
  • Ricbet

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

yarn install v1.22.22
[1/4] Resolving packages...
warning eslint@8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other options.
warning eslint > @humanwhocodes/config-array@0.13.0: Use @eslint/config-array instead
warning eslint > file-entry-cache > flat-cache > rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
warning eslint > @humanwhocodes/config-array > @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
warning eslint > file-entry-cache > flat-cache > rimraf > glob@7.2.3: Glob versions prior to v9 are no longer supported
warning eslint > file-entry-cache > flat-cache > rimraf > glob > inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
warning eslint-import-resolver-typescript > glob@7.2.3: Glob versions prior to v9 are no longer supported
error Couldn't find any versions for "@opensumi/ide-dev-tool" that matches "workspace:*"
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1557188 and 7c37a4e.

📒 Files selected for processing (1)
  • packages/components/src/recycle-tree/tree/TreeNode.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/components/src/recycle-tree/tree/TreeNode.ts
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: 🚀🚀🚀 Next Version for pull request
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: build-windows
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: ubuntu-latest, Node.js 20.x

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

railway-app bot commented Sep 3, 2024

🚅 Previously deployed to Railway in the core project. Environment has been deleted.

@opensumi opensumi bot added the 🎨 feature feature required label Sep 3, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Outside diff range, codebase verification and nitpick comments (7)
packages/connection/src/common/constants.ts (1)

3-6: 代码变更看起来不错!

新增的 chunkSize 常量与 PR 的目标一致,用于实现 WebSocket 连接的分块数据传输。8MB 的大小选择合理。

建议为注释添加英文翻译,以便于国际协作。例如:

 /**
  * 分片大小, 8MB
+ * Chunk size, 8MB
  */
 export const chunkSize = 8 * 1024 * 1024;
packages/connection/src/common/connection/drivers/ws-websocket.ts (1)

11-11: 新增的 decoder 成员看起来不错,但可以考虑添加注释。

新增的 decoder 成员用于处理传入的消息,这是一个很好的改进。

建议为 decoder 成员添加简短的注释,解释其用途和重要性。例如:

// 用于解码和处理传入的 WebSocket 消息
protected decoder = new LengthFieldBasedFrameDecoder();
packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (2)

20-30: 更新构造函数和 send 方法

构造函数中新增的事件监听器和 send 方法的重写都很好地实现了分块数据传输的目标。这些更改与 PR 的目标一致,有助于提高大文件传输的性能。

然而,我建议在 send 方法中添加一个注释,解释为什么要使用分块传输,以及 chunkSize 的值是多少。这将有助于其他开发者理解这个实现的目的。

建议在 send 方法开始处添加如下注释:

/**
 * 发送数据,使用分块传输以避免大文件传输时的线程阻塞。
 * 每个块的大小为 ${chunkSize} 字节。
 */

87-103: 新增 dataHandler 方法和更新 dispose 方法

新增的 dataHandler 方法很好地处理了不同类型的传入数据,包括 Blob、ArrayBuffer 和 Buffer。这种实现提高了代码的健壮性。dispose 方法的更新确保了正确的资源清理。

然而,我建议在 dataHandler 方法中添加错误处理,以防在数据处理过程中出现异常。

建议在 dataHandler 方法中添加错误处理:

private dataHandler = (e: MessageEvent) => {
  // ... 现有代码 ...
  buffer.then((v) => this.decoder.push(new Uint8Array(v, 0, v.byteLength)))
    .catch((error) => {
      console.error('处理传入消息时出错:', error);
      // 可以在这里添加额外的错误处理逻辑
    });
};
packages/connection/src/common/connection/drivers/frame-decoder.ts (2)

67-69: 数据发送逻辑的更新

这个更改与新的监听器管理方法保持一致,直接调用 _onDataListener 而不是发出事件。

建议添加一个空值检查,以增加代码的健壮性:

if (this._onDataListener && typeof this._onDataListener === 'function') {
  this._onDataListener(binary);
}

这样可以避免在 _onDataListener 不是函数时可能出现的运行时错误。


166-166: dispose 方法的更新

这个更改与新的监听器管理方法保持一致,但是使用 undefined 而不是 nullonData 方法中的做法不一致。

为了保持一致性,建议将这行改为:

this._onDataListener = null;

这样可以确保在整个类中使用相同的方式来表示监听器被移除。

packages/connection/__test__/common/frame-decoder.test.ts (1)

Line range hint 38-121: 总结:数据包构造方法的系统性更新

整个文件中,所有数据包构造的地方都一致地添加了 .dump() 方法的调用。这种系统性的更改可能反映了 LengthFieldBasedFrameDecoder 类实现的变化。

建议:

  1. 确保这些更改与 LengthFieldBasedFrameDecoder 类的最新实现保持同步。
  2. 考虑在测试文件的开头添加一个注释,解释为什么需要使用 .dump() 方法,以及它对测试结果的影响。
  3. 如果 .dump() 方法改变了数据包的结构或内容,可能需要更新其他依赖于这些测试的部分。

@bytemain bytemain changed the title feat: send data by chunk in websocket WIP: feat: send data by chunk in websocket Sep 3, 2024
@bytemain bytemain closed this Sep 13, 2024
@Aaaaash Aaaaash reopened this Dec 3, 2024
@Aaaaash Aaaaash force-pushed the feat/chunk-ws-payload branch from 9d104a8 to a8ae167 Compare February 6, 2025 08:02
@Aaaaash Aaaaash changed the title WIP: feat: send data by chunk in websocket feat: send data by chunk in websocket Feb 6, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (2)
packages/connection/src/common/connection/drivers/ws-websocket.ts (1)

27-29: ⚠️ Potential issue

建议在消息处理添加错误处理机制

在构造函数中,当调用 this.decoder.push(data) 时,建议添加错误处理,以防止在数据解码过程中出现未捕获的异常导致程序崩溃。

您可以考虑如下修改:

this.socket.on('message', (data: Buffer) => {
  try {
    this.decoder.push(data);
  } catch (error) {
    console.error('Error decoding message:', error);
    // 根据需要添加进一步的错误处理逻辑
  }
});
packages/connection/src/common/connection/drivers/frame-decoder.ts (1)

27-38: 🛠️ Refactor suggestion

将多监听器改为单一监听器可能限制功能

当前的修改将事件监听机制从支持多个监听器更改为仅支持单个监听器,这可能限制了代码的可扩展性,影响到需要添加多个监听器的需求。

建议考虑继续支持多个监听器,您可以使用数组来保存监听器列表,并在接收到数据时遍历调用。

例如:

private _onDataListeners: Array<(data: Uint8Array) => void> = [];

onData(listener: (data: Uint8Array) => void) {
  this._onDataListeners.push(listener);
  return {
    dispose: () => {
      const index = this._onDataListeners.indexOf(listener);
      if (index > -1) {
        this._onDataListeners.splice(index, 1);
      }
    },
  };
}

protected async processBuffers(): Promise<void> {
  // ... existing code ...
  if (this._onDataListeners.length > 0) {
    for (const listener of this._onDataListeners) {
      try {
        await Promise.resolve().then(() => listener(binary));
      } catch (error) {
        console.error('[Frame Decoder] Error in data listener:', error);
      }
    }
  }
}
🧹 Nitpick comments (6)
packages/connection/src/common/connection/drivers/ws-websocket.ts (1)

19-19: 建议将 MAX_QUEUE_SIZE 设为可配置项

当前 MAX_QUEUE_SIZE 被设置为固定值100,建议将其设为可配置参数,以便根据实际需求调整队列大小,增强系统的灵活性。

packages/components/src/recycle-tree/tree/TreeNode.ts (1)

1388-1434: 优化了 hardReloadChildren 方法,提升了大数据量时的性能

通过多项优化措施,如预先分配数组大小、采用动态批处理、缓存频繁访问的属性和方法、使用 for 循环替代 for...of,以及合并监听器更新等,显著提高了处理大量节点时的性能。

然而,hardReloadChildren 方法较长且复杂,建议将部分逻辑提取到辅助函数中,以提高代码的可读性和可维护性。

packages/connection/__test__/browser/index.test.ts (1)

28-34: 建议优化错误处理

在发送响应消息时,建议添加错误处理逻辑。

建议修改如下:

-            connection.send(
+            connection.send(
               furySerializer.serialize({
                 id: msgObj.id,
                 kind: 'server-ready',
                 traceId: '',
               }),
-            );
+            ).catch((error) => {
+              console.error('Failed to send server-ready message:', error);
+            });
packages/connection/__test__/common/frame-decoder.test.ts (2)

38-40: 测试数据构造方法改进

使用 dump() 方法处理数据包的实现很好,但建议添加对异常情况的测试。

建议添加以下测试场景:

  1. 处理超大数据包时的内存使用情况
  2. 数据包损坏的情况
  3. 网络延迟模拟

52-57: 建议优化测试用例结构

当前的混合数据包测试实现较好,但可以进一步提升可维护性。

建议将测试数据的创建逻辑抽取为独立的辅助函数:

+function createMixedPacket(payload: Uint8Array, headerSize: number = 1024) {
+  const sumiPacket = LengthFieldBasedFrameDecoder.construct(payload).dump();
+  const newPacket = createPayload(headerSize + sumiPacket.byteLength);
+  newPacket.set(sumiPacket, headerSize);
+  return [newPacket, payload] as const;
+}
+
 const mixedPackets = [p1m, p5m].map((v) => {
-  const sumiPacket = LengthFieldBasedFrameDecoder.construct(v).dump();
-  const newPacket = createPayload(1024 + sumiPacket.byteLength);
-  newPacket.set(sumiPacket, 1024);
-  return [newPacket, v] as const;
+  return createMixedPacket(v);
 });
packages/connection/src/common/buffers/buffers.ts (1)

76-107: 建议重构以减少代码重复

slice4 方法与 slice 方法有大量重复代码。建议重构以提高可维护性。

建议使用以下实现:

   slice4(start: number) {
-    let end = start + 4;
-    const buffers = this.buffers;
-
-    if (end > this.size) {
-      end = this.size;
-    }
-
-    if (start >= end) {
-      return emptyBuffer;
-    }
-
-    let startBytes = 0;
-    let si = 0;
-    for (; si < buffers.length && startBytes + buffers[si].length <= start; si++) {
-      startBytes += buffers[si].length;
-    }
-
-    const target = buffer4Capacity;
-
-    let ti = 0;
-    for (let ii = si; ti < end - start && ii < buffers.length; ii++) {
-      const len = buffers[ii].length;
-
-      const _start = ti === 0 ? start - startBytes : 0;
-      const _end = ti + len >= end - start ? Math.min(_start + (end - start) - ti, len) : len;
-      copy(buffers[ii], target, ti, _start, _end);
-      ti += _end - _start;
-    }
-
-    return target;
+    const end = start + 4;
+    if (start >= end || start >= this.size) {
+      return emptyBuffer;
+    }
+    const slice = this.slice(start, end);
+    if (slice === emptyBuffer) {
+      return emptyBuffer;
+    }
+    copy(slice, buffer4Capacity, 0, 0, slice.length);
+    return buffer4Capacity;
   }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3c2cfb and dc07a19.

📒 Files selected for processing (11)
  • packages/components/src/recycle-tree/tree/TreeNode.ts (3 hunks)
  • packages/connection/__test__/browser/index.test.ts (2 hunks)
  • packages/connection/__test__/common/frame-decoder.test.ts (4 hunks)
  • packages/connection/src/common/buffers/buffers.ts (3 hunks)
  • packages/connection/src/common/connection/drivers/frame-decoder.ts (5 hunks)
  • packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (3 hunks)
  • packages/connection/src/common/connection/drivers/stream.ts (1 hunks)
  • packages/connection/src/common/connection/drivers/ws-websocket.ts (2 hunks)
  • packages/connection/src/common/constants.ts (1 hunks)
  • packages/connection/src/node/common-channel-handler.ts (1 hunks)
  • packages/core-browser/__tests__/bootstrap/connection.test.ts (2 hunks)
🔇 Additional comments (9)
packages/connection/src/common/connection/drivers/ws-websocket.ts (1)

114-121: 在 dispose 方法中拒绝所有待发送消息是一个很好的实践

通过在连接关闭时拒绝所有待发送的消息,可以防止出现未处理的 Promise,保持应用程序状态的一致性。

packages/components/src/recycle-tree/tree/TreeNode.ts (2)

42-50: 优化了 spliceArray 函数,提高了性能

新的实现通过在没有修改操作时直接返回原数组,并使用 sliceconcat 方法替代展开运算符,减少了不必要的操作,提高了函数的性能。


1381-1381: 在异常处理中添加了 return false;

catch 块中添加了 return false;,确保在发生异常时方法返回正确的状态,符合方法的返回类型,提高了代码的健壮性。

packages/connection/src/common/constants.ts (1)

3-6: 新增了 chunkSize 常量

添加了用于数据传输分片处理的常量 chunkSize,大小为 1 * 1024 * 1024(1MB),为后续的 WebSocket 数据分片发送提供了基础。

packages/core-browser/__tests__/bootstrap/connection.test.ts (1)

3-3: 使用 sleep 函数优化了延迟处理

引入并使用了 sleep 函数,替代了原先基于 setTimeout 的 Promise 实现,简化了代码,提高了可读性和可维护性。

Also applies to: 38-40

packages/connection/src/node/common-channel-handler.ts (1)

45-45: 代码优化得当!

直接在 receiveConnection 方法中创建 WSWebSocketConnection 实例,避免了不必要的中间变量,使代码更简洁。

packages/connection/__test__/browser/index.test.ts (1)

24-25: 测试用例实现合理!

使用 WSWebSocketConnection 替代直接的 WebSocket 操作,更好地测试了新的分块传输功能。

packages/connection/src/common/buffers/buffers.ts (2)

305-309: 实现正确且符合设计模式

read4 方法的实现简洁明了,并且与现有的 read 方法保持一致的设计模式。


8-8: 注意:重用缓冲区可能导致并发问题

buffer4Capacity 作为静态缓冲区被重用可能在并发场景下导致数据竞争。建议添加相关文档说明此限制。

建议添加以下注释说明:

+/**
+ * 警告:此缓冲区在多个调用之间共享和重用。
+ * 在并发场景下使用时需要确保正确的同步。
+ */
 export const buffer4Capacity = new Uint8Array(4);
✅ Verification successful

建议为 buffer4Capacity 添加警告注释

在文件 packages/connection/src/common/buffers/buffers.ts 的第 8 行中,声明的静态缓冲区 buffer4Capacity 被设计为重复使用以避免重复分配。但需要注意的是,在并发使用场景下,该缓冲区的重用可能会引发数据竞争问题。建议在该常量前添加具体的警告注释,说明该缓冲区在并发环境下需要额外注意并做好同步保护,例如:

+/**
+ * 警告:此缓冲区在多个调用之间共享和重用。
+ * 在并发场景下使用时需要确保正确的同步,以避免数据竞争。
+ */
 export const buffer4Capacity = new Uint8Array(4);

这样能更好地提醒开发者注意潜在的并发问题。

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (2)

30-58: 建议优化分块发送逻辑

当前实现中,每个分块都创建新的 Promise,这可能导致不必要的开销。考虑以下优化建议:

  1. 使用批量处理减少 Promise 创建次数
  2. 添加可配置的延迟以控制发送速率

建议重构为:

 private async processSendQueue() {
   if (this.sending) { return; }
   this.sending = true;

   while (this.sendQueue.length > 0) {
     const { data, resolve, reject } = this.sendQueue[0];
     try {
       const handle = LengthFieldBasedFrameDecoder.construct(data).dumpAndOwn();
       const packet = handle.get();

+      const chunks = [];
       for (let i = 0; i < packet.byteLength; i += chunkSize) {
-        await new Promise<void>((resolve) => {
-          const chunk = packet.subarray(i, Math.min(i + chunkSize, packet.byteLength));
-          this.socket.send(chunk);
-          resolve();
-        });
+        chunks.push(packet.subarray(i, Math.min(i + chunkSize, packet.byteLength)));
       }
+      
+      for (const chunk of chunks) {
+        this.socket.send(chunk);
+        await new Promise(resolve => setTimeout(resolve, 0));  // 控制发送速率
+      }

       handle.dispose();
       resolve();
     } catch (error) {

60-65: 建议添加方法文档

send 方法的实现看起来不错,但建议添加 JSDoc 文档说明以下内容:

  1. 方法的异步特性
  2. 可能的错误类型
  3. 分块发送的大小限制

建议添加如下文档:

+/**
+ * 异步发送数据,支持大文件分块传输
+ * @param data 要发送的数据
+ * @returns Promise 在数据完全发送后 resolve,发送出错时 reject
+ * @throws Error 当 WebSocket 连接关闭或发送失败时
+ */
 send(data: Uint8Array): Promise<void> {
packages/connection/src/common/connection/drivers/frame-decoder.ts (2)

92-126: 建议优化帧处理性能

当前实现中的异步处理可能导致不必要的延迟。建议:

  1. 优化内存使用,避免频繁的数据拷贝
  2. 考虑使用 TypedArray 的视图而不是切片

建议添加性能监控:

 protected async readFrame(): Promise<boolean> {
+  const startTime = performance.now();
   try {
     const found = this.readLengthField();
     if (!found) {
       return true;
     }

     const start = this.cursor.offset;
     const end = start + this.contentLength;

     if (end > this.buffers.byteLength) {
       return true;
     }

     const binary = this.buffers.slice(start, end);

     // 立即清理已处理的数据
     this.buffers.splice(0, end);
     this.reset();

     if (this._onDataListener) {
       try {
         await Promise.resolve().then(() => this._onDataListener?.(binary));
       } catch (error) {
         console.error('[Frame Decoder] Error in data listener:', error);
       }
     }

+    const duration = performance.now() - startTime;
+    if (duration > 100) {  // 记录处理时间超过 100ms 的帧
+      console.warn('[Frame Decoder] Slow frame processing:', {
+        size: binary.byteLength,
+        duration
+      });
+    }

     return false;
   } catch (error) {

212-225: 建议完善静态方法文档

construct 静态方法的实现看起来不错,但建议添加更详细的文档说明其用途和注意事项。

建议添加如下文档:

+/**
+ * 构造一个新的帧
+ * @param content 要编码的内容
+ * @returns 返回一个新的 writer 实例,调用者负责调用 dispose 释放资源
+ * @throws Error 当编码失败时抛出错误
+ * @example
+ * const writer = LengthFieldBasedFrameDecoder.construct(data);
+ * try {
+ *   const frame = writer.dumpAndOwn();
+ *   // 使用 frame
+ * } finally {
+ *   writer.dispose();
+ * }
+ */
 static construct(content: Uint8Array) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc07a19 and d4f0f4a.

📒 Files selected for processing (3)
  • packages/connection/src/common/connection/drivers/frame-decoder.ts (5 hunks)
  • packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (3 hunks)
  • packages/connection/src/common/connection/drivers/stream.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/connection/src/common/connection/drivers/stream.ts
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: build-windows
  • GitHub Check: ubuntu-latest, Node.js 20.x
🔇 Additional comments (3)
packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (1)

20-28: 构造函数可见性变更提醒

将构造函数改为 protected 限制了类的实例化方式,现在只能通过 static forURL 方法创建实例。这增强了封装性,但可能影响现有代码的扩展性。

请确认此更改不会影响现有的继承类。

packages/connection/src/common/connection/drivers/frame-decoder.ts (2)

27-38: 监听器实现限制提醒

当前实现将多监听器模式改为单一监听器模式,这可能在某些场景下造成限制。建议考虑以下几点:

  1. 是否有需要支持多个监听器的场景
  2. 是否需要提供移除监听器的方法

请确认这个更改不会影响现有的使用场景。


54-69: 🛠️ Refactor suggestion

建议改进大数据包处理策略

当前实现在收到超大数据包时直接截断,这可能导致数据不完整。建议:

  1. 考虑拒绝而不是截断超大数据包
  2. 添加数据包大小的日志记录

建议修改为:

 push(chunk: Uint8Array): void {
-  // 如果新数据太大,只接收部分
   if (chunk.byteLength > LengthFieldBasedFrameDecoder.MAX_FRAME_SIZE) {
-    console.warn('[Frame Decoder] Chunk too large, truncating');
-    chunk = chunk.slice(0, LengthFieldBasedFrameDecoder.MAX_FRAME_SIZE);
+    console.error('[Frame Decoder] Chunk size exceeds limit:', {
+      size: chunk.byteLength,
+      limit: LengthFieldBasedFrameDecoder.MAX_FRAME_SIZE
+    });
+    throw new Error('Chunk size exceeds maximum frame size');
   }

Likely invalid or redundant comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/connection/src/common/connection/drivers/frame-decoder.ts (2)

13-20: 常量定义优化建议

新增的常量定义提高了代码的可维护性,但建议考虑以下几点:

  1. MAX_FRAME_SIZE 的大小(1MB)可能需要根据实际使用场景进行调整
  2. MAX_ITERATIONS 的值(50)应该添加注释说明选择该值的原因

建议添加以下注释:

- private static readonly MAX_FRAME_SIZE = 1 * 1024 * 1024; // 1MB
+ private static readonly MAX_FRAME_SIZE = 1 * 1024 * 1024; // 1MB - 根据WebSocket最佳实践设置的单帧大小限制
- private static readonly MAX_ITERATIONS = 50;
+ private static readonly MAX_ITERATIONS = 50; // 单次处理最大迭代次数,防止过度占用CPU

Also applies to: 27-29


54-69: 异步处理优化值得肯定

代码通过以下方式优化了性能:

  1. 通过 processingPromise 确保同时只有一个处理过程
  2. 每处理10个包就让出执行权,防止长时间占用主线程
  3. 设置了最大迭代次数,避免死循环

建议考虑添加可配置的处理间隔时间,例如:

+ private static readonly YIELD_INTERVAL = 10; // 每处理多少个包让出执行权
  // ...
- if (iterations % 10 === 0) {
+ if (iterations % LengthFieldBasedFrameDecoder.YIELD_INTERVAL === 0) {

Also applies to: 71-90

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d4f0f4a and fdf3d82.

📒 Files selected for processing (1)
  • packages/connection/src/common/connection/drivers/frame-decoder.ts (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: ubuntu-latest, Node.js 20.x
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: build-windows
🔇 Additional comments (1)
packages/connection/src/common/connection/drivers/frame-decoder.ts (1)

30-38: 监听器管理方式的重大变更

这个变更将之前基于 Emitter 的多监听器方法改为了单一监听器方法。虽然这简化了事件处理机制,但也限制了类只能同时处理一个监听器。

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
packages/connection/src/common/connection/drivers/frame-decoder.ts (3)

53-82: 处理队列的实现值得肯定,建议补充日志

当前实现通过 Promise 队列和迭代限制很好地解决了处理阻塞问题。建议添加以下改进:

 if (iterations % 10 === 0) {
+  console.debug('[Frame Decoder] Yielding after processing 10 frames');
   await new Promise((resolve) => setTimeout(resolve, 0));
 }

85-119: 建议优化内存管理

当前实现在处理大量数据时可能会占用较多内存。建议添加以下优化:

 const binary = this.buffers.slice(start, end);
+// 设置一个合理的缓冲区大小限制
+const MAX_BUFFER_SIZE = 50 * 1024 * 1024; // 50MB
+if (this.buffers.byteLength > MAX_BUFFER_SIZE) {
+  console.warn('[Frame Decoder] Buffer size exceeds limit, clearing');
+  this.buffers.clear();
+  this.reset();
+}

205-218: 建议添加输入验证

当前实现没有对输入内容进行验证。建议添加:

 static construct(content: Uint8Array) {
+  if (!content || content.byteLength === 0) {
+    throw new Error('Content cannot be empty');
+  }
   const writer = BinaryWriter({});
packages/connection/__test__/common/frame-decoder.test.ts (3)

38-40: 建议添加更多边界测试用例

当前测试用例覆盖了基本场景,建议添加以下边界情况:

  1. 空数据包
  2. 最大帧大小的数据包
  3. 无效的帧长度

74-86: 建议添加超时处理

当前异步测试可能在数据未到达时无限等待。建议添加:

-      const result = await new Promise<Uint8Array>((resolve) => {
+      const result = await new Promise<Uint8Array>((resolve, reject) => {
+        const timeout = setTimeout(() => {
+          reject(new Error('Timeout waiting for data'));
+        }, 5000);
         decoder.onData((data) => {
+          clearTimeout(timeout);
           resolve(data)
         });

89-115: 建议增强测试断言

当前测试只验证了数据内容,建议添加以下断言:

  1. 验证接收顺序
  2. 验证接收时间间隔
  3. 验证内存使用情况
 receivedData.forEach((data, index) => {
   fastExpectBufferEqual(data, purePackets[index][1]);
+  // 验证接收时间间隔不超过100ms
+  if (index > 0) {
+    expect(receivedTimes[index] - receivedTimes[index - 1]).toBeLessThan(100);
+  }
 });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4382cd9 and e5dcf34.

📒 Files selected for processing (2)
  • packages/connection/__test__/common/frame-decoder.test.ts (4 hunks)
  • packages/connection/src/common/connection/drivers/frame-decoder.ts (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: build-windows
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: ubuntu-latest, Node.js 20.x
🔇 Additional comments (1)
packages/connection/src/common/connection/drivers/frame-decoder.ts (1)

29-37: 监听器管理方式需要重新考虑

当前实现将多监听器模式改为单一监听器模式,这可能会限制类的使用场景。

建议:

  1. 考虑使用数组存储多个监听器
  2. 添加文档说明当前限制
  3. 实现 removeListener 方法使 API 更完整

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/connection/src/common/fury-extends/one-of.ts (1)

71-73: 增强了错误处理机制

添加了默认分支来处理无效的索引值,这样可以及时发现序列化过程中的异常情况。

建议进一步改进错误消息,提供更多上下文信息:

-        throw new Error('unknown index: ' + idx);
+        throw new Error(`无效的序列化索引: ${idx},有效范围为 0-${cap - 1}`);
packages/connection/__test__/node/index.test.ts (1)

65-66: 消息处理逻辑重构

重构后的消息处理逻辑更加清晰和类型安全:

  • 使用了 wrappedConnection 进行序列化处理
  • 通过 onMessage 方法统一处理消息
  • 使用了类型化的消息处理机制

建议添加错误处理机制:

 wrappedConnection.onMessage((msg: ChannelMessage) => {
+  try {
     if (msg.kind === 'server-ready') {
       if (msg.id === 'TEST_CHANNEL_ID') {
         channel.dispatch(msg);
       }
     }
+  } catch (error) {
+    console.error('消息处理失败:', error);
+    // 可以在这里添加适当的错误处理逻辑
+  }
 });

Also applies to: 71-77

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5dcf34 and d88dce0.

📒 Files selected for processing (2)
  • packages/connection/__test__/node/index.test.ts (2 hunks)
  • packages/connection/src/common/fury-extends/one-of.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: build-windows
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: ubuntu-latest, Node.js 20.x
🔇 Additional comments (1)
packages/connection/__test__/node/index.test.ts (1)

11-11: 类型导入优化

通过导入 ChannelMessage 类型,增强了消息处理的类型安全性。

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
packages/connection/src/common/connection/drivers/ws-websocket.ts (2)

32-80: 建议优化内存使用。

当前实现在处理大文件时可能会占用较多内存。建议考虑以下优化:

  1. 使用 ArrayBufferSharedArrayBuffer 来减少内存复制
  2. 考虑使用 WebSocket.bufferedAmount 来控制发送速率
private async processSendQueue() {
  if (this.sending) return;
  this.sending = true;

  while (this.sendQueue.length > 0) {
    const { data, resolve, reject } = this.sendQueue[0];
    let handle: { get: () => Uint8Array; dispose: () => void } | null = null;

    try {
      handle = LengthFieldBasedFrameDecoder.construct(data).dumpAndOwn();
      const packet = handle.get();
      
      const sendChunk = async (start: number) => {
        while (start < packet.byteLength && (this.socket as any).bufferedAmount < 1024 * 1024) {
          if (!this.isOpen()) throw new Error('连接已关闭');
          
          const end = Math.min(start + chunkSize, packet.byteLength);
          const chunk = packet.subarray(start, end);
          
          await new Promise<void>((resolve, reject) => {
            this.socket.send(chunk, { binary: true }, (error?: Error) => {
              error ? reject(error) : resolve();
            });
          });
          
          start = end;
        }
        
        if (start < packet.byteLength) {
          await new Promise(resolve => setTimeout(resolve, 50));
          await sendChunk(start);
        }
      };

      await sendChunk(0);
      resolve();
    } catch (error) {
      reject(error instanceof Error ? error : new Error(String(error)));
    } finally {
      handle?.dispose();
      this.pendingSize -= this.sendQueue[0].data.byteLength;
      this.sendQueue.shift();
    }
  }

  this.sending = false;
}

114-123: 建议添加日志记录。

在资源清理时添加日志记录有助于问题排查:

 dispose(): void {
+  console.log('[WSWebSocket] 开始清理资源');
   this.socket.removeAllListeners();
   while (this.sendQueue.length > 0) {
     const { reject } = this.sendQueue.shift()!;
+    console.warn('[WSWebSocket] 取消未发送的消息');
     reject(new Error('Connection disposed'));
   }
   this.pendingSize = 0;
   this.sending = false;
+  console.log('[WSWebSocket] 资源清理完成');
 }
packages/connection/src/common/connection/drivers/frame-decoder.ts (3)

56-94: 异步处理逻辑的改进建议

当前的异步处理实现有以下优点:

  1. 使用 processingPromise 确保同时只有一个处理过程
  2. 通过 MAX_ITERATIONS 限制避免无限循环
  3. 使用 setImmediate 防止长时间阻塞

建议进一步改进错误处理:

 this.processingPromise = this.processBuffers().finally(() => {
   this.processingPromise = null;
+}).catch((error) => {
+  console.error('[Frame Decoder] Error in processBuffers:', error);
+  this.reset();
 });

96-130: 建议增强错误处理和日志记录

当前的错误处理可以通过添加更多上下文信息来改进:

-console.error('[Frame Decoder] Error in data listener:', error);
+console.error('[Frame Decoder] Error in data listener:', {
+  error,
+  contentLength: this.contentLength,
+  bufferLength: this.buffers.byteLength,
+  state: this.state,
+  cursorOffset: this.cursor.offset
+});

216-229: 建议改进构造函数的错误处理

当前的错误处理可以更具体地处理不同类型的错误:

 try {
   writer.buffer(indicator);
   writer.uint32(content.byteLength);
   writer.buffer(content);
   return writer;
 } catch (error) {
-  console.warn('[Frame Decoder] Error constructing frame:', error);
+  if (error instanceof TypeError) {
+    console.warn('[Frame Decoder] Invalid buffer type:', error);
+  } else if (error instanceof RangeError) {
+    console.warn('[Frame Decoder] Buffer size exceeds limits:', error);
+  } else {
+    console.warn('[Frame Decoder] Unexpected error constructing frame:', error);
+  }
   throw error;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d88dce0 and 9f169dd.

📒 Files selected for processing (3)
  • packages/connection/__test__/node/ws-channel.test.ts (3 hunks)
  • packages/connection/src/common/connection/drivers/frame-decoder.ts (6 hunks)
  • packages/connection/src/common/connection/drivers/ws-websocket.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: build-windows
  • GitHub Check: ubuntu-latest, Node.js 20.x
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: build (macos-latest, 20.x)
🔇 Additional comments (6)
packages/connection/src/common/connection/drivers/ws-websocket.ts (3)

11-24: 队列管理的实现看起来不错!

接口定义清晰,队列大小限制和状态追踪的实现都很合理。


27-29: 建议在消息处理中添加错误处理。

为了提高代码的健壮性,建议在处理接收到的消息时添加错误处理:

-this.socket.on('message', (data: Buffer) => {
-  this.decoder.push(data);
-});
+this.socket.on('message', (data: Buffer) => {
+  try {
+    this.decoder.push(data);
+  } catch (error) {
+    console.error('解码器处理数据时发生错误:', error);
+    // 可以在这里添加重试逻辑或其他错误处理
+  }
+});

98-100: 实现简洁有效!

使用 decoder 处理消息的方式很好,保持了代码的简洁性。

packages/connection/__test__/node/ws-channel.test.ts (1)

88-88: 测试用例的改进很合理!

  1. 添加索引到消息内容增加了测试的多样性
  2. 增加超时时间适应了分块发送的实现

这些改动使测试更加健壮。

Also applies to: 98-98, 152-152

packages/connection/src/common/connection/drivers/frame-decoder.ts (2)

29-37: 监听器管理方式的重大变更

这个变更将之前基于 Emitter 的多监听器方法改为了单一监听器方法。虽然这简化了事件处理机制,但也限制了类只能同时处理一个监听器。

建议考虑使用数组来存储多个监听器,以提供更大的灵活性。


13-20: 🛠️ Refactor suggestion

建议添加最大帧大小常量

为了防止处理过大的数据帧导致内存问题,建议添加最大帧大小常量:

+/**
+ * 最大帧大小限制(例如:10MB)
+ */
+const MAX_FRAME_SIZE = 10 * 1024 * 1024;

Likely invalid or redundant comment.

Copy link

codecov bot commented Feb 10, 2025

Codecov Report

Attention: Patch coverage is 84.84848% with 30 lines in your changes missing coverage. Please review.

Project coverage is 53.86%. Comparing base (840ef8c) to head (7c37a4e).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...tion/src/common/connection/drivers/ws-websocket.ts 77.35% 11 Missing and 1 partial ⚠️
...ommon/connection/drivers/reconnecting-websocket.ts 81.39% 7 Missing and 1 partial ⚠️
...ion/src/common/connection/drivers/frame-decoder.ts 90.32% 6 Missing ⚠️
...kages/connection/src/common/fury-extends/one-of.ts 0.00% 2 Missing ⚠️
packages/connection/src/common/buffers/buffers.ts 96.00% 1 Missing ⚠️
...connection/src/common/connection/drivers/stream.ts 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3988      +/-   ##
==========================================
+ Coverage   53.83%   53.86%   +0.03%     
==========================================
  Files        1650     1650              
  Lines      101511   101648     +137     
  Branches    21968    21991      +23     
==========================================
+ Hits        54648    54753     +105     
- Misses      38966    38995      +29     
- Partials     7897     7900       +3     
Flag Coverage Δ
jsdom 49.36% <83.33%> (+0.03%) ⬆️
node 12.25% <64.64%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Aaaaash
Copy link
Member

Aaaaash commented Feb 10, 2025

/next

@opensumi
Copy link
Contributor

opensumi bot commented Feb 10, 2025

🎉 PR Next publish successful!

3.7.1-next-1739178290.0

@Aaaaash
Copy link
Member

Aaaaash commented Feb 10, 2025

/next

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/file-service/src/node/hosted/watcher.host.service.ts (3)

139-141: 建议增加错误处理机制

异步操作的引入提高了代码的健壮性,但建议添加 try-catch 块来处理潜在的异步错误。

建议修改为:

 Disposable.create(async () => {
-  await this.unrecursiveFileSystemWatcher!.unwatchFileChanges(uri.toString());
-  this.logger.log('dispose unrecursive watcher: ', uri.toString());
+  try {
+    await this.unrecursiveFileSystemWatcher!.unwatchFileChanges(uri.toString());
+    this.logger.log('dispose unrecursive watcher: ', uri.toString());
+  } catch (error) {
+    this.logger.error('Failed to unwatch file changes: ', error);
+  }
   this.watchedDirs.delete(uri.toString());
   this.WATCHER_HANDLERS.delete(watcherId);
 }),

156-158: 建议增加错误处理机制

与非递归监视器类似,递归监视器的异步操作也需要错误处理机制。

建议修改为:

 Disposable.create(async () => {
-  this.logger.log('dispose recursive watcher: ', uri.toString());
-  await this.recursiveFileSystemWatcher!.unwatchFileChanges(uri.toString());
+  try {
+    this.logger.log('dispose recursive watcher: ', uri.toString());
+    await this.recursiveFileSystemWatcher!.unwatchFileChanges(uri.toString());
+  } catch (error) {
+    this.logger.error('Failed to unwatch recursive changes: ', error);
+  }
   this.watchedDirs.delete(uri.toString());
   this.WATCHER_HANDLERS.delete(watcherId);
 }),

110-174: 建议优化大文件处理机制

根据PR的目标(通过分块发送来处理大文件),建议在文件监视器中也实现相应的优化。当监视的是大文件时,可能需要特殊处理以避免性能问题。

建议考虑以下几点:

  1. 为大文件设置单独的处理策略
  2. 实现文件大小检查
  3. 针对大文件可以采用节流(throttle)机制来减少事件触发频率

需要您确认是否需要我提供具体的实现方案?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1ae5587 and e61375d.

📒 Files selected for processing (1)
  • packages/file-service/src/node/hosted/watcher.host.service.ts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: build-windows
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: ubuntu-latest, Node.js 20.x
🔇 Additional comments (1)
packages/file-service/src/node/hosted/watcher.host.service.ts (1)

82-82: 优化监视器集合的清理时机

在重新监视之前删除监视器,可以防止潜在的竞态条件。

@opensumi
Copy link
Contributor

opensumi bot commented Feb 10, 2025

🎉 PR Next publish successful!

3.7.1-next-1739181952.0

@Aaaaash
Copy link
Member

Aaaaash commented Feb 10, 2025

/next

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/file-service/src/node/hosted/recursive/file-service-watcher.ts (1)

261-264: 路径处理优化建议

代码改动通过使用 FileUri.fsPath(realPath).toString() 统一了路径格式,这是一个好的改进。不过建议进一步优化:

  1. 考虑将路径格式化逻辑抽取为一个工具函数,以确保整个代码库中路径处理的一致性
  2. 可以在 WATCHER_HANDLERS 的类型定义中明确键的类型为 string,以更好地表达意图
-  private WATCHER_HANDLERS = new Map<
-    string,
-    { path: string; handlers: ParcelWatcher.SubscribeCallback[]; disposable: IDisposable }
-  >();
+  private normalizeWatchPath(path: string): string {
+    return FileUri.fsPath(path).toString();
+  }
+
+  private WATCHER_HANDLERS = new Map<
+    string,
+    { path: string; handlers: ParcelWatcher.SubscribeCallback[]; disposable: IDisposable }
+  >();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e61375d and 8e39bff.

📒 Files selected for processing (1)
  • packages/file-service/src/node/hosted/recursive/file-service-watcher.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: 🚀🚀🚀 Next Version for pull request
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: ubuntu-latest, Node.js 20.x
  • GitHub Check: build-windows

@opensumi
Copy link
Contributor

opensumi bot commented Feb 10, 2025

🎉 PR Next publish successful!

3.7.1-next-1739183195.0

@Aaaaash
Copy link
Member

Aaaaash commented Feb 10, 2025

/next

@opensumi
Copy link
Contributor

opensumi bot commented Feb 10, 2025

🎉 PR Next publish successful!

3.7.1-next-1739183529.0

@Aaaaash Aaaaash force-pushed the feat/chunk-ws-payload branch from c76f711 to 1ae5587 Compare February 11, 2025 01:38
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
packages/connection/__test__/common/frame-decoder.test.ts (2)

74-86: 改进了流解码测试的实现方式

  1. 使用 async/await 替代回调,提高了代码可读性
  2. 添加了 dispose() 确保资源正确释放
  3. 通过 Promise 优化了异步流程控制

117-232: 新增全面的边界场景测试

新增测试覆盖了以下关键场景:

  1. 分块传输(验证指示符分割情况)
  2. 高频小数据包(验证性能和稳定性)
  3. 内存稳定性(验证内存泄漏)
  4. 空数据包处理
  5. 并发推送

这些测试用例显著提高了代码质量和可靠性。建议考虑添加:

  1. 极限并发场景测试
  2. 网络延迟模拟
  3. 错误恢复机制测试
packages/connection/__test__/common/buffers.test.ts (3)

269-280: 建议增加更多边界情况的测试

当前的边界测试仅覆盖了chunk边界的开始和结束位置,建议添加以下场景:

  • 跨多个chunk的边界切片
  • 空chunk的处理
  • 最大chunk大小的边界值
 describe('Edge Case Slicing', () => {
   const buffer = create([0, 1, 2, 3, 4, 5], [3, 3]);
 
   it('should handle start at chunk boundary', () => {
     expect(buffer.slice(3, 5)).toEqual(new Uint8Array([3, 4]));
   });
 
   it('should handle end at chunk boundary', () => {
     expect(buffer.slice(2, 3)).toEqual(new Uint8Array([2]));
   });
+
+  it('should handle cross-chunk slicing', () => {
+    const multiChunk = create([0, 1, 2, 3, 4, 5], [2, 2, 2]);
+    expect(multiChunk.slice(1, 4)).toEqual(new Uint8Array([1, 2, 3]));
+  });
+
+  it('should handle empty chunks', () => {
+    const withEmpty = create([0, 1, 2], [1, 0, 2]);
+    expect(withEmpty.slice(0, 3)).toEqual(new Uint8Array([0, 1, 2]));
+  });
 });

368-388: 性能测试需要更严格的断言

当前的性能测试仅验证了执行时间,建议添加内存使用的监控。

 it('should handle slicing 1MB data under 50ms', () => {
+  const startHeap = process.memoryUsage().heapUsed;
   const start = performance.now();
   const slice = largeBuffer.slice(0, 1024 * 1024);
   const duration = performance.now() - start;
+  const heapUsed = process.memoryUsage().heapUsed - startHeap;

   expect(duration).toBeLessThan(50);
   expect(slice.byteLength).toBe(1024 * 1024);
+  expect(heapUsed).toBeLessThan(2 * 1024 * 1024); // 确保内存使用不超过2MB
 });

401-412: createEnhanced函数的错误处理可以更完善

建议添加对负数chunk大小的明确错误提示。

 function createEnhanced(xs: number[], split: number[]): Buffers {
+  if (split.some(size => size < 0)) {
+    throw new Error('Chunk size cannot be negative');
+  }
   const bufs = new Buffers();
   let offset = 0;
   split.forEach((chunkSize) => {
     if (chunkSize > 0) {
       const chunk = new Uint8Array(xs.slice(offset, offset + chunkSize));
       bufs.push(chunk);
       offset += chunkSize;
     }
   });
   return bufs;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c76f711 and dc5ae5f.

📒 Files selected for processing (2)
  • packages/connection/__test__/common/buffers.test.ts (2 hunks)
  • packages/connection/__test__/common/frame-decoder.test.ts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: build-windows
  • GitHub Check: ubuntu-latest, Node.js 20.x
  • GitHub Check: unittest (macos-latest, 18.x, node)
🔇 Additional comments (4)
packages/connection/__test__/common/frame-decoder.test.ts (3)

38-40: 优化了数据包构造方式

通过统一使用 .dump() 方法序列化数据包,确保了数据包格式的一致性。


64-64: 测试用例更新符合新的数据包构造标准

使用 .dump() 方法确保测试数据的一致性和可靠性。


89-115: 新增多帧处理测试用例

完善了以下测试场景:

  1. 多帧数据的顺序接收
  2. 数据完整性验证
  3. 资源清理

建议添加以下场景的测试:

  1. 帧大小边界条件
  2. 错误的帧格式处理
packages/connection/__test__/common/buffers.test.ts (1)

257-267: 测试用例覆盖了空缓冲区的基本操作

测试用例完整地验证了空缓冲区的行为,包括长度、切片和位置查询等操作。

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (2)

127-130: ⚠️ Potential issue

需要添加错误处理机制

当前的 arrayBufferHandler 实现缺少错误处理,可能在解码失败时导致程序崩溃。

建议添加错误处理:

 private arrayBufferHandler = (e: MessageEvent<ArrayBuffer>) => {
-  const buffer: ArrayBuffer = e.data;
-  this.decoder.push(new Uint8Array(buffer, 0, buffer.byteLength));
+  try {
+    const buffer: ArrayBuffer = e.data;
+    this.decoder.push(new Uint8Array(buffer, 0, buffer.byteLength));
+  } catch (error) {
+    console.error('[ReconnectingWebSocket] 处理 ArrayBuffer 消息时出错:', error);
+    this.emit('error', error);
+  }
 };

133-135: ⚠️ Potential issue

需要正确处理队列中的待处理 Promise

dispose 方法中,直接清空队列可能导致未处理的 Promise 永远挂起。

建议在清空队列前拒绝所有待处理的 Promise:

 dispose(): void {
   this.socket.removeEventListener('message', this.arrayBufferHandler);
+  // 拒绝所有待处理的 Promise
+  while (this.sendQueue.length > 0) {
+    const { reject } = this.sendQueue.shift()!;
+    reject(new Error('连接已关闭'));
+  }
-  this.sendQueue = [];
   this.sending = false;
 }
🧹 Nitpick comments (9)
packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (3)

23-27: 建议增强二进制类型处理的错误信息

binaryType 为 'blob' 时抛出的错误信息过于简单。建议提供更详细的错误信息,包括支持的类型和解决方案。

建议修改为:

-      throw new Error('blob is not implemented');
+      throw new Error('WebSocket binary type "blob" is not supported. Please use "arraybuffer" instead.');

44-50: 建议优化分块发送的错误处理和性能监控

当前的分块发送实现缺少重试机制和性能监控。

建议添加以下功能:

  1. 重试机制
  2. 发送进度回调
  3. 性能指标收集
+  private async sendChunk(chunk: Uint8Array, retries = 3): Promise<void> {
+    for (let attempt = 1; attempt <= retries; attempt++) {
+      try {
+        await new Promise<void>((resolve, reject) => {
+          const start = performance.now();
+          this.socket.send(chunk);
+          const duration = performance.now() - start;
+          console.debug(`Chunk sent in ${duration}ms`);
+          resolve();
+        });
+        return;
+      } catch (error) {
+        if (attempt === retries) throw error;
+        await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
+      }
+    }
+  }

 for (let i = 0; i < packet.byteLength; i += chunkSize) {
-  await new Promise<void>((resolve) => {
-    const chunk = packet.subarray(i, Math.min(i + chunkSize, packet.byteLength));
-    this.socket.send(chunk);
-    resolve();
-  });
+  const chunk = packet.subarray(i, Math.min(i + chunkSize, packet.byteLength));
+  await this.sendChunk(chunk);
+  this.emit('progress', {
+    sent: i + chunk.byteLength,
+    total: packet.byteLength
+  });
 }

15-19: 建议添加类级别的文档注释

作为一个重要的连接类,建议添加详细的类级别文档,说明其功能、使用方式和注意事项。

+/**
+ * 实现了具有重连功能的 WebSocket 连接类
+ * 
+ * 特性:
+ * - 支持自动重连
+ * - 支持大文件分块发送
+ * - 使用 LengthFieldBasedFrameDecoder 处理消息
+ * 
+ * @example
+ * ```typescript
+ * const connection = ReconnectingWebSocketConnection.forURL('ws://example.com');
+ * connection.onMessage((data) => console.log('收到消息:', data));
+ * await connection.send(new Uint8Array([1, 2, 3]));
+ * ```
+ */
 export class ReconnectingWebSocketConnection extends BaseConnection<Uint8Array> {
packages/connection/__test__/common/buffers.test.ts (6)

270-285: 建议改进测试结构

should handle splice at exact chunk boundary 测试用例移入 Edge Case Slicing describe 块内,以保持测试结构的一致性。

 describe('Edge Case Slicing', () => {
   const buffer = create([0, 1, 2, 3, 4, 5], [3, 3]);

   it('should handle start at chunk boundary', () => {
     expect(buffer.slice(3, 5)).toEqual(new Uint8Array([3, 4]));
   });

   it('should handle end at chunk boundary', () => {
     expect(buffer.slice(2, 3)).toEqual(new Uint8Array([2]));
   });
+
+  it('should handle splice at exact chunk boundary', () => {
+    const buffer = createEnhanced([0, 1, 2, 3, 4, 5], [3, 3]);
+    buffer.splice(3, 2, new Uint8Array([99]));
+    expect(buffer.slice()).toEqual(new Uint8Array([0, 1, 2, 99, 5]));
+  });
 });
-it('should handle splice at exact chunk boundary', () => {
-  const buffer = createEnhanced([0, 1, 2, 3, 4, 5], [3, 3]);
-  buffer.splice(3, 2, new Uint8Array([99]));
-  expect(buffer.slice()).toEqual(new Uint8Array([0, 1, 2, 99, 5]));
-});

330-340: 建议添加空缓冲区的slice4测试

为确保完整的测试覆盖率,建议添加对空缓冲区调用slice4方法的测试用例。

 describe('slice4 Special Cases', () => {
+  it('should handle slice4 on empty buffer', () => {
+    const buffer = new Buffers();
+    expect(buffer.slice4(0)).toEqual(new Uint8Array([0, 0, 0, 0]));
+  });
+
   it('should handle partial slice4', () => {
     const buffer = create([1, 2, 3], [3]);
     expect(buffer.slice4(2)).toEqual(new Uint8Array([3, 0, 0, 0]));
   });

343-359: 建议添加错误情况测试

Cursor高级操作测试应该包含错误情况的处理,比如:

  • 移动到负偏移量
  • 移动到超出范围的位置
 describe('Cursor Advanced Operations', () => {
   const buffer = create([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [3, 3, 4]);

+  it('should throw on negative moveTo', () => {
+    const cursor = buffer.cursor();
+    expect(() => cursor.moveTo(-1)).toThrow('out of range');
+  });
+
+  it('should throw on overflow moveTo', () => {
+    const cursor = buffer.cursor();
+    expect(() => cursor.moveTo(buffer.byteLength + 1)).toThrow('out of range');
+  });

362-370: 建议增强资源清理验证

建议添加内存泄漏检测,确保所有内部引用都被正确清理。

 describe('Resource Management', () => {
   it('should clear resources on dispose', () => {
     const buffer = create([1, 2, 3], [3]);
+    const cursor = buffer.cursor();
     buffer.dispose();

     expect(buffer.buffers).toEqual([]);
     expect(buffer.byteLength).toBe(0);
+    expect(() => cursor.value).toThrow();  // 确保游标引用被清理
   });
 });

373-407: 建议优化性能测试阈值设置

建议将性能测试的时间阈值设置为可配置的参数,以适应不同的测试环境:

  • CI/CD环境可能需要更宽松的阈值
  • 本地开发环境可以使用更严格的阈值
+const PERFORMANCE_THRESHOLDS = {
+  SLICE_THRESHOLD_MS: process.env.SLICE_THRESHOLD_MS || 50,
+  SPLICE_THRESHOLD_MS: process.env.SPLICE_THRESHOLD_MS || 1000,
+};
+
 describe('Performance Tests', () => {
   // ...
   it('should handle slicing 1MB data under 50ms', () => {
     const start = performance.now();
     const slice = largeBuffer.slice(0, 1024 * 1024);
     const duration = performance.now() - start;

-    expect(duration).toBeLessThan(50);
+    expect(duration).toBeLessThan(PERFORMANCE_THRESHOLDS.SLICE_THRESHOLD_MS);
     expect(slice.byteLength).toBe(1024 * 1024);
   });

420-431: 建议添加输入参数验证

createEnhanced 函数应该验证 split 数组的有效性:

  • 确保 split 数组不为空
  • 验证 split 数组的和不超过 xs 数组的长度
 function createEnhanced(xs: number[], split: number[]): Buffers {
+  if (!split.length) {
+    throw new Error('Split array cannot be empty');
+  }
+  const totalSize = split.reduce((sum, size) => sum + size, 0);
+  if (totalSize > xs.length) {
+    throw new Error('Split sizes exceed source array length');
+  }
   const bufs = new Buffers();
   let offset = 0;
   split.forEach((chunkSize) => {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc5ae5f and 4f872ce.

📒 Files selected for processing (2)
  • packages/connection/__test__/common/buffers.test.ts (2 hunks)
  • packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: ubuntu-latest, Node.js 20.x
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: build-windows
🔇 Additional comments (6)
packages/connection/src/common/connection/drivers/reconnecting-websocket.ts (2)

67-71: 实现良好,已修复之前的 Promise 处理问题

新的实现正确处理了 Promise 的 resolve 和 reject,并通过队列确保了消息的有序发送。


86-88: 消息处理逻辑优化得当

使用 decoder 处理消息的方式更加清晰和可维护。

packages/connection/__test__/common/buffers.test.ts (4)

258-267: 测试用例设计合理!

空缓冲区测试用例覆盖了关键的边界情况,包括长度检查、切片操作和越界访问。


287-297: 错误处理测试设计完善!

非法索引访问测试用例很好地覆盖了负索引和越界索引的场景。


299-315: 性能测试中的内存使用需要优化

当前的大缓冲区测试创建了1MB的连续数组,这可能导致内存压力。建议使用更小的块大小进行测试。


318-327: 跨块操作测试设计合理!

跨chunk拼接测试用例很好地验证了修改后的缓冲区内容和被移除的元素。

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/connection/__test__/common/frame-decoder.test.ts (2)

74-87: 测试代码现代化改进

将回调式的测试模式改为使用 async/await,提高了代码的可读性和可维护性。这种方式更容易处理异步操作,并且能更好地处理错误情况。


132-232: 全面的边缘场景测试补充

新增了多个重要的测试场景,显著提升了测试覆盖率:

  1. 分块传输测试(132-154行):验证解码器对分片数据的处理能力
  2. 高频小数据包测试(157-177行):验证解码器在高压力下的稳定性
  3. 内存泄漏测试(180-199行):确保长期运行时的内存稳定性
  4. 空载荷测试(202-212行):验证对边界情况的处理
  5. 并发推送测试(215-232行):验证并发场景下的正确性

这些测试用例的添加极大地提高了代码的可靠性。

建议考虑添加以下场景的测试:

  1. 错误数据的处理
  2. 超大帧的处理限制
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f872ce and 1557188.

📒 Files selected for processing (1)
  • packages/connection/__test__/common/frame-decoder.test.ts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: build-windows
  • GitHub Check: ubuntu-latest, Node.js 20.x
🔇 Additional comments (2)
packages/connection/__test__/common/frame-decoder.test.ts (2)

38-40: 优化了数据包的构造方式

通过在构造时立即调用 .dump(),确保了测试数据的一致性和可靠性。这种方式更符合实际使用场景,因为在实际应用中数据包总是会被序列化的。


89-116: 新增多帧处理测试

新增了对多帧数据的处理测试,这对于验证解码器在处理连续数据流时的正确性非常重要。测试用例设计合理,覆盖了以下关键点:

  • 多帧数据的正确解析
  • 数据完整性验证
  • 内存资源的及时释放

@Ricbet
Copy link
Member

Ricbet commented Feb 20, 2025

/next

@opensumi
Copy link
Contributor

opensumi bot commented Feb 20, 2025

🎉 PR Next publish successful!

3.7.1-next-1740016426.0

@opensumi
Copy link
Contributor

opensumi bot commented Feb 20, 2025

🎉 PR Next publish successful!

3.7.2-next-1740016705.0

@Ricbet Ricbet requested a review from erha19 February 20, 2025 05:41
@Ricbet Ricbet merged commit feca922 into main Feb 20, 2025
13 checks passed
@Ricbet Ricbet deleted the feat/chunk-ws-payload branch February 20, 2025 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎨 feature feature required
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants