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

s3, s3-multipart, tus: queue requests for soken token for remote files #3797

Merged
merged 7 commits into from Jun 7, 2022

Conversation

Murderlon
Copy link
Member

@Murderlon Murderlon commented May 30, 2022

Fixes #3640

Tested with 300+ files. But things can go wrong with a limit of 0 or 1 on a slow connection for instance. But it's still an improvement.

Before

Screenshot 2022-05-30 at 18 32 31

After

Screenshot 2022-05-30 at 18 28 01

@Murderlon Murderlon requested review from mifi and aduh95 May 30, 2022 16:34
@Murderlon Murderlon marked this pull request as ready for review May 31, 2022 12:15
@aduh95
Copy link
Member

aduh95 commented May 31, 2022

I'm getting this concerning error message in the console:

Socket.js:81 Error: Cannot mark a queued request as done: this indicates a bug
    at Object.done (RateLimitedQueue.js:91:15)
    at Function.<anonymous> (index.js:597:23)
    at emitAll (index.js:131:14)
    at Object.emit (index.js:33:7)
    at UppySocket.emit (Socket.js:68:19)
    at WebSocket.#handleMessage (Socket.js:78:12)

it does solve the websocket timeout issue

It does still timeout when I try to upload 300 files with a limit of 1 (it seems to work for the first 140 files then errors start popping up). I might still be an improvement over the current situation, but I wanted to point it out for completeness sake.

@Murderlon
Copy link
Member Author

Murderlon commented Jun 1, 2022

I tested this on Tus with Google Drive with a limit of 2 and I can successfully upload 313 files. Doing the same on the main branch will almost immediately result in errors and every retry will also have some failures. It might not be perfect for all combinations of settings but generally it should do the trick.

Perhaps we should discourage a limit of 1 (and 0)?

@aduh95
Copy link
Member

aduh95 commented Jun 1, 2022

I tested this on Tus with Google Drive with a limit of 2 and I can successfully upload 313 files.

I just tried and it's failing for me. In fact I think it's failing even with the default limit of 6, I guess my connection is not as fast as it needs to be.

Doing the same on the main branch will almost immediately result in errors and every retry will also have some failures. It might not be perfect for all combinations of settings but generally it should do the trick.

Same for me, I agree it's an improvement. Maybe we need to rename this PR as it looks like it does not fix timeout but rather the error we have on main.

Perhaps we should discourage a limit of 1 (and 0)?

Keep in mind that the RateLimiterQueue will set itself to 1 when getting a 429 response (then tries to increase its limit until it finds a sweet spot that does not trigger 429s anymore).
A limit of 0 is treated as Infinity, I think it's already discouraged (at least implicitly).

Copy link
Contributor

@mifi mifi left a comment

Choose a reason for hiding this comment

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

nice job!
I think if it's true that "RateLimiterQueue will set itself to 1 when getting a 429 response", then we need to find out why it fails with limit 1, because an uploader that becomes unstable only in some hard-to-test scenarios (429), is going to cause problems for us in the future and will be really tricky to fix later.

this.uppy.setFileState(file.id, { serverToken: res.token })
await this.connectToServerSocket(this.uppy.getFile(file.id))
if (file.serverToken) {
return this.connectToServerSocket(file)
Copy link
Contributor

Choose a reason for hiding this comment

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

what's the purpose of calling this here? I thought this should only happen after await this.#queueRequestSocketToken(file) has returned?

Copy link
Member Author

Choose a reason for hiding this comment

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

If we retry then this is called again but we don't need a new server token, we already have it. In some other instances it's also possible to already have it

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, a comment could be nice

const serverToken = await this.#queueRequestSocketToken(file)

this.uppy.setFileState(file.id, { serverToken })
return this.connectToServerSocket(this.uppy.getFile(file.id))
Copy link
Contributor

Choose a reason for hiding this comment

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

couldn't we just do return this.connectToServerSocket(file) ?

Copy link
Member

Choose a reason for hiding this comment

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

Could the await make the file instance outdated? If the file was removed by the user while this code was waiting for the RateLimitedQueue to dispatch maybe? If so, it wouldn't be equivalent to return this.connectToServerSocket(file)

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's indeed safer to do it this way. It's also cheap so it doesn't matter much

@Murderlon
Copy link
Member Author

I think if it's true that "RateLimiterQueue will set itself to 1 when getting a 429 response", then we need to find out why it fails with limit 1, because an uploader that becomes unstable only in some hard-to-test scenarios (429), is going to cause problems for us in the future and will be really tricky to fix later.

Note that is doesn't inherently fail on limit of 1! Only with lots of files on a slower connection it might happen. So this is still an improvement.

@Murderlon Murderlon changed the title Fix websocket timeout for rate limited remote files through Companion Improve websocket timeouts for rate limited remote files through Companion Jun 7, 2022
@Murderlon Murderlon changed the title Improve websocket timeouts for rate limited remote files through Companion s3, s3-multipart, tus: queue requests for soken token for remote files Jun 7, 2022
@aduh95 aduh95 merged commit df15292 into main Jun 7, 2022
@aduh95 aduh95 deleted the websocket-timeout branch June 7, 2022 16:08
@github-actions github-actions bot mentioned this pull request Jun 7, 2022
github-actions bot added a commit that referenced this pull request Jun 7, 2022
| Package                | Version | Package                | Version |
| ---------------------- | ------- | ---------------------- | ------- |
| @uppy/aws-s3           |   2.2.1 | @uppy/tus              |   2.4.1 |
| @uppy/aws-s3-multipart |   2.4.1 | @uppy/url              |   2.2.0 |
| @uppy/companion-client |   2.2.1 | @uppy/xhr-upload       |   2.1.2 |
| @uppy/core             |   2.3.1 | @uppy/robodog          |   2.8.0 |
| @uppy/react            |   2.2.2 | uppy                   |  2.12.0 |
| @uppy/remote-sources   |   0.1.0 |                        |         |

- @uppy/remote-sources: Add @uppy/remote-sources preset/plugin (Artur Paikin / #3676)
- @uppy/react: Reset uppy instance when React component is unmounted (Tomasz Pęksa / #3814)
- @uppy/aws-s3-multipart,@uppy/aws-s3,@uppy/tus: queue socket token requests for remote files (Merlijn Vos / #3797)
- @uppy/xhr-upload: replace `ev.target.status` with `xhr.status` (Wes Sankey / #3782)
- @uppy/core: fix `TypeError` when file was deleted (Antoine du Hamel / #3811)
- @uppy/robodog: fix linter warnings (Antoine du Hamel / #3808)
- meta: fix GHA workflow for prereleases (Antoine du Hamel)
- @uppy/aws-s3-multipart: allow `companionHeaders` to be modified with `setOptions` (Paulo Lemos Neto / #3770)
- @uppy/url: enable passing optional meta data to `addFile` (Brad Edelman / #3788)
- @uppy/url: fix `getFileNameFromUrl` (Brad Edelman / #3804)
- @uppy/tus: make onShouldRetry type optional (Merlijn Vos / #3800)
- doc: fix React examples (Antoine du Hamel / #3799)
- meta: add GHA workflow for prereleases (Antoine du Hamel)
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.

"Timed out waiting for socket" when attempting to upload multiple large files via Companion
3 participants