Skip to content

feat(lib-storage): S3TransferManager - #7731

Open
smilkuri wants to merge 40 commits into
mainfrom
tm-initial
Open

feat(lib-storage): S3TransferManager#7731
smilkuri wants to merge 40 commits into
mainfrom
tm-initial

Conversation

@smilkuri

@smilkuri smilkuri commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Issue

Internal JS-6610

Description

This PR adds upload functionality to the S3 Transfer Manager, building upon previous PR that wasn't merged. This implementation focuses specifically on single object and multipart upload capabilities commit.

Testing

 yarn test:e2e
  ✓ src/s3-transfer-manager/S3TransferManager.e2e.spec.ts (26 tests) 274836ms

 Test Files  1 passed | 1 skipped (2)
      Tests  26 passed | 92 skipped (118)
   Start at  16:42:31
   Duration  275.51s (transform 665ms, setup 0ms, import 1.13s, tests 274.84s, environment 0ms)

 RUN  v4.0.18 /local/home/smilkuri/aws-sdk-js-v3/lib/lib-storage

Checklist

  • If the PR is a feature, add integration tests (*.integ.spec.ts).
  • If you wrote E2E tests, are they resilient to concurrent I/O?
  • If adding new public functions, did you add the @public tag and enable doc generation on the package?

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@smilkuri
smilkuri requested a review from a team as a code owner February 11, 2026 16:50
* @internal
*/
private calculatePartSize(contentLength: number): { partSize: number; expectedPartsCount: number } {
const partSize = Math.max(this.targetPartSizeBytes, Math.floor(contentLength / 10_000));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

pretty sure this needs to be Math.ceil(contentLength / 10_000). check out this issue aws/aws-sdk-net#4332 you might want to add a test case for this

@GarrettBeatty GarrettBeatty left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

added one comment. i can review rest of pr later if wanted

@smilkuri
smilkuri force-pushed the tm-initial branch 4 times, most recently from 1bea79a to 8263551 Compare February 18, 2026 22:04
@smilkuri
smilkuri force-pushed the tm-initial branch 2 times, most recently from 7ff3777 to 31dd619 Compare February 26, 2026 20:35
@smilkuri
smilkuri force-pushed the tm-initial branch 2 times, most recently from 2841950 to 16d443e Compare March 12, 2026 16:59
(response.Body as any).getReader = function () {
return reader;
};
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what is this override of getReader doing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

uses the same reader instance, when stream is already locked.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

that seems dangerous and counter to the point of having a lockable stream

Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts
private readonly eventListeners: TransferEventListeners;
private readonly abortCleanupFunctions = new WeakMap<AbortSignal, () => void>();
private readonly maxConcurrentRequests: number;
private readonly maxConcurrentUploads: number;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

explain the state variables.

what is targetPartSizeBytes? why is checksumAlgorithm a property of this class?

what is the difference between maxConcurrentRequests and maxConcurrentUploads?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

  • targetPartSizeBytes // Size of a part user wants to use for transfer

  • maxConcurrentRequests // This used only for downloads which determines max no of parts that can be downloaded concurrently or call it like max no of getObject requests that can be made.

  • maxConcurrentUploads // This is for upload, max no of parts that can be uploaded concurrently

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maxConcurrentRequests should be renamed. Uploads are requests too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

renamed it to maxInMemoryParts according to specification wording

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maxInMemoryParts is misleading. Are the parts fully buffered in memory? I think not.

And it only applies to downloads?

It should be called maxConcurrentDownloads

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

+1 there is two separate things. maxConcurrentDownloads (number of http requests) and maxInMemoryParts (number of parts buffered in memory) (if applicable)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

+1 to Garrett's comment. Yeah, was a bit confused here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed maxInMemoryParts for downloads because we only initiate the next request after a stream is consumed. So the number of buffered parts can't exceed maxConcurrentDownloads.

Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts
Comment thread lib/lib-storage/src/s3-transfer-manager/types.ts
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
Comment thread lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts Outdated
@smilkuri
smilkuri force-pushed the tm-initial branch 3 times, most recently from eea6c87 to b20066e Compare April 16, 2026 11:43
lukasdchang and others added 6 commits June 2, 2026 03:06
feat(lib-storage): added doc comments for interfaces and types

feat(lib-storage): address PR review feedback for transfer manager types

feat(lib-storage): addressed minor review feedback

feat(lib-storage): added example code file

feat(lib-storage): changed "handler" to "listener" and changed type file names

feat(lib-storage): created TransferManager class and constructor with defaults

feat(lib-storage): beginning implementation for download(), created TM index file

feat(lib-storage): range multipart download

feat(lib-storage): download() improvements post pair-programming

feat(lib-storage): transfermanager download() iteration

feat(lib-storage): transfermanager interation post pair programming

feat(lib-storage): joinstream iteration, web stream not fully functional

feat(lib-storage): both cases of range download handled

feat(lib-storage): range download working

chore: acquire lock on streams

feat(lib-storage): bug fixes and test env setup

feat(lib-storage): implemented dispatchEvent(), need to add dispatches for complete and fail

feat(lib-storage): requests array, eventListeners revision, needs more testing

feat(lib-storage): addEventListener & removeEventListener implemented, needs support for options

feat(lib-storage): added support for adding event listeners at request level

feat(lib-storage): added ETag verification for subsequent GetObjectRequests

feat(lib-storage): totalSize changes, and added validateExpectedRanges()

feat(lib-storage): addEventListener once parameter, type fixes

feat(lib-storage): s3TM SEP test cases and added TODOs

feat(lib-storage): validateExpectedRanges fixes and unit tests

feat(lib-storage): added check in validateExpectedRanges if final part doesnt download total object

feat(lib-storage): s3TM constructor and add event listener tests

feat(lib-storage): addEventListener tests and error checking adjustment and dispatchEvent tests

feat(lib-storage): added test cases
@smilkuri
smilkuri force-pushed the tm-initial branch 5 times, most recently from 0dedb30 to 3da7b90 Compare June 2, 2026 17:42
},
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/config": "workspace:3.1058.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

don't use internally, import the implementation pkg

@kuhe kuhe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

will be split into multiple PRs, blocking this

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.

5 participants