Skip to content

增加 Amazon S3 存储#1189

Draft
CodFrm wants to merge 8 commits intorelease/v1.3from
feat/storage-s3
Draft

增加 Amazon S3 存储#1189
CodFrm wants to merge 8 commits intorelease/v1.3from
feat/storage-s3

Conversation

@CodFrm
Copy link
Member

@CodFrm CodFrm commented Feb 3, 2026

概述 Descriptions

尝试了下 openspec,还是有些问题,先存一下,后续再继续处理

close #1146

变更内容 Changes

截图 Screenshots

@CodFrm CodFrm changed the title [v1.4] 增加 Amazon S3 存储 增加 Amazon S3 存储 Feb 3, 2026
@CodFrm CodFrm marked this pull request as draft February 3, 2026 04:11
@CodFrm CodFrm linked an issue Feb 3, 2026 that may be closed by this pull request
@cyfung1031
Copy link
Collaborator

cyfung1031 commented Feb 3, 2026

还是有些问题

ba73e4a

你看一看


1. 大文件读取内存占用过高(最可能卡住 openspec 测试的地方)

问题
S3FileReader.read() 把所有 chunk 收集到数组 chunks: Uint8Array[],然后一次性计算总长度、创建大 Uint8Array 并 memcpy。
如果文件是 200MB+(常见于用户脚本备份包或大压缩文件),浏览器内存容易爆掉(尤其是移动端或低配设备)。

解决方案

  • 如果只需要 Blob,直接用 stream 包装成 Blob,不需要收集所有 chunk 到内存。
  • 如果需要 string,也可以用 streaming decode(但浏览器 TextDecoderStream 支持度好,可以先转 Blob 再 decode)。
  • 优先推荐返回 stream/Blob 方式,上层再决定是否全读。

额外建议:如果上层 FileSystem 接口允许,考虑让 read() 返回 ReadableStream<Uint8Array>Response 对象,让调用方自己消费 stream。

2. write 方法对 content 类型支持不完整 & 未做类型防护

问题
只处理 string | Blob,如果传入其他类型(例如 ArrayBuffer、Uint8Array、null),会直接把非法值传给 Body,导致 SDK 抛出模糊错误或静默失败。

解决方案

  • 增加类型守卫,明确抛出 TypeError。
  • 支持更多常见类型(ArrayBuffer / Uint8Array)。

3. forcePathStyle 硬编码为 true,导致 AWS 官方区域可能用不了 virtual-hosted style

问题
forcePathStyle: true 对 AWS 官方 S3 不是最佳实践(会用 path-style URL,已被逐渐弃用),对 MinIO 等兼容服务则是必须的。硬编码会导致部分用户配置失败。

解决方案

  • 在 UI 多加一个 checkbox 参数:usePathStyle(默认 true,兼容大多数自建/国内云)。
  • 或自动检测:如果 endpoint 包含 amazonaws.com,设为 false。

4. Metadata 键名和格式不规范

问题

  • createtime 建议用小写 + 连字符(如 x-amz-meta-create-time),但 SDK 会自动加 x-amz-meta- 前缀。
  • toString() 格式不标准(可能是 "Wed Feb 03 2026 12:34:56 GMT+0000"),解析困难。

解决方案
用 ISO 8601 格式 + 规范键名。

5. openDir 方法中重复创建 client(浪费资源 & 凭证冗余)

问题
openDir 又 new 一个 S3FileSystem,但传了空字符串的 AK/SK,导致逻辑不清晰。

解决方案
复用原有 client,只修改 basePath。

总结优先级修复顺序建议

  1. 先修 read() 内存问题(改成 Blob([stream]))——最影响大文件同步体验
  2. write() 类型安全 + metadata 格式
  3. usePathStyle 参数(UI + factory 也要改)
  4. 优化 openDir 复用 client
  5. 后续:加单元测试(尤其是大文件、权限错误、MinIO 兼容)

这些改动后,S3 支持应该能稳定很多。如果后续作者有更具体的报错日志或测试案例,可以再针对性调整。

@cyfung1031
Copy link
Collaborator

參考一下吧


这些问题大多是“隐形坑”,在小文件/本地测试时不明显,但真实同步场景(大文件、多目录、各种 S3 兼容服务)很容易暴露。

6. endpoint 配置不完整(缺少协议,SDK 容易报 InvalidEndpoint)

问题
用户在 UI 输入自定义 endpoint(如 s3.minio.example.comhttps://obs.ap-southeast-1.myhuaweicloud.com/),但代码直接 config.endpoint = endpoint,AWS SDK v3 要求 endpoint 是完整 URL(带 https://)。缺少协议会导致 InvalidEndpoint 或连接失败。

解决方案

  • UI 提示用户输入完整 URL(含协议)。
  • 或代码中自动补全 https://(常见做法,但不完美)。
  • 最好:加校验,如果没协议就 prepend https://

7. list() 方法分页无上限 + 内存累积(大目录风险)

问题
list() 用 while 循环 + continuationToken 取所有对象,但没有 max-keys 限制或总迭代上限。如果 bucket/prefix 下有上万对象,会:

  • 发起大量 API 请求(费用 & 延迟)
  • 所有 FileInfo 对象累积在内存数组中,可能 OOM

解决方案

  • 加参数 maxKeys(默认 1000)
  • 或加总上限(如 5000 对象),超限抛警告
  • 改成异步生成器(yield)返回,避免一次性全载入(但需改上层接口)

8. verify() 方法的错误映射不完整(漏掉常见权限/网络错误)

问题
只特殊处理了几个 credential 相关的错误码,其他如 AccessDeniedPermanentRedirectNetworkingError 等直接 re-throw,用户看到一堆英文 SDK 错误,不友好。

解决方案
扩展 catch 块,映射更多常见错误到中文提示。

9. openDir() 中重复构造对象但凭证传空字符串(逻辑冗余)

问题
已经提到过,但再强调:传空 AK/SK 只是占位,实际靠 fs.client = this.client 复用。但如果未来 client 需要 refresh(STS token),子实例会失效。

解决方案
让 openDir 只改 basePath,复用整个实例(或用工厂方法)。

当前整体评估

  • PR 刚开(今天),作者很可能刚写完基本框架,跑 openspec 测试时卡在大文件读取内存兼容 endpoint/region 的签名失败 上(最常见两类)。
  • 其他问题多是“健壮性/生产级”性质,小规模测试不一定触发。
  • 没有发现崩溃级 bug(如语法错、import 缺失),主要是内存、兼容、错误友好度问题。

建议作者:

  • 加 endpoint 协议补全 + forcePathStyle UI 开关
  • 跑不同服务(AWS、MinIO、阿里/华为/腾讯云 OBS)测试 verify + list + read/write

@cyfung1031
Copy link
Collaborator

cyfung1031 commented Feb 3, 2026

PutObjectCommand 的 Body 可以直接写入 Blob content


为什么直接传 Blob 更好?

  • 零拷贝 / 流式友好:SDK 内部会用 Blob.stream() 或类似方式分块上传,不用一次性读全文件到内存。
  • 类型安全:最新 SDK 版本对 Blob 的支持已稳定(早期有 issue,现在基本 OK)。
  • 与浏览器 API 一致:File / Blob 来自 <input type="file"> 或 fetch response,最自然就是直接传。
  • 如果 content 来自 ArrayBuffer 或 Uint8Array,也可以直接传(SDK 接受)。

(alias) type StreamingBlobPayloadInputTypes = string | Blob | Uint8Array | Buffer | Stream.Readable | Uint8Array | ReadableStream
import StreamingBlobPayloadInputTypes
@public
This union represents a superset of the compatible types you can use for streaming payload inputs.

FAQ: Why does the type union mix mutually exclusive runtime types, namely Node.js and browser types?

There are several reasons:

For backwards compatibility.

As a convenient compromise solution so that users in either environment may use the types without customization.

The SDK does not have static type information about the exact implementation of the HTTP RequestHandler being used in your client(s) (e.g. fetch, XHR, node:http, or node:http2), given that it is chosen at runtime. There are multiple possible request handlers in both the Node.js and browser runtime environments.

Rather than restricting the type to a known common format (Uint8Array, for example) which doesn't include a universal streaming format in the currently supported Node.js versions, the type declaration is widened to multiple possible formats. It is up to the user to ultimately select a compatible format with the runtime and HTTP handler implementation they are using.

Usage: The typical solution we expect users to have is to manually narrow the type when needed, picking the appropriate one out of the union according to the runtime environment and specific request handler. There is also the type utility "NodeJsClient", "BrowserClient" and more exported from this package. These can be applied at the client level to pre-narrow these streaming payload blobs. For usage see the readme.md in the root of the @smithy/types NPM package.

@CodFrm
Copy link
Member Author

CodFrm commented Feb 3, 2026

openspec 是一个新的vibe coding方法论,你的AI理解似乎有点问题;

我只是拿这个需求来试试,还没完成,我提交上来先占个位,不过感觉你好像快弄完了。👀

@cyfung1031
Copy link
Collaborator

openspec 是一个新的vibe coding方法论,你的AI理解似乎有点问题;

我只是拿这个需求来试试,还没完成,我提交上来先占个位,不过感觉你好像快弄完了。👀

哈哈。。AI嘛
但我没测试过 AI这些修改。 都只是让你参详一下
应该不是完成吧
我也不太清楚你写的那个 FileSystem 详细
还是要交给你

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 希望同步功能可以增加 Amazon S3 选项

2 participants