-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
flow control for file uploads #20315
flow control for file uploads #20315
Conversation
67fcd17
to
54111eb
Compare
The watch channel can emit events even after `.close()` is called, which can cause issues in the `kdump/test-config-client.js` QUnit test if the timing of the file write changes (which it is about to do, in a upcoming commit which reimplements fsreplace1 asynchronously). Removing the event listener is a sure way to ensure we won't get further events.
pkg/lib/cockpit-upload-helper.ts
Outdated
if (window.debugging == 'all' || window.debugging?.includes('upload')) | ||
console.debug('debug[upload]', ...args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally this is:
pkg/systemd/services.jsx: console.debug.apply(console, arguments);
Can we, keep things consistent :)
54111eb
to
edb3645
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This got force-pushed underneath me, so sending the first half of my pending review.
edb3645
to
e69ac8e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... and the rest of the review. Thanks!
e69ac8e
to
e678f1b
Compare
Our previous reason for avoiding tempfile.NamedTemporaryFile() was that we didn't want to chown() after the fact, but we've crossed that bridge already since 72027c1, so we may as well go all the way. Rewrite things as a single run() function using NamedTemporaryFile as a context manager. This is a fairly substantial simplification. We also make the channel properly asynchronous by dispatching the actual write to an executor. We also add fdatasync(), which we were missing before. We need to make a minor adjustment to AsyncChannel to support sending close arguments, similar to the way we handle them on GeneratorChannel.
e678f1b
to
2825145
Compare
382ed70 changed the EOF return value of `AsyncChannel.read()` from `b''` to `None` to account for the possibility that the user might have sent an empty message (which has a semantic meaning in at least one other channel — `fsreplace1`). Unfortunately, it also introduced a comment documenting the old return value behaviour. Update the comment to reflect the new reality.
In Cockpit Navigator we want to support uploading large files and sent data in chunks. As fsreplace1 lacks flow control navigator itself has to make sure it doesn't flood the channel with data but before this commit couldn't determine when to back off. Add a new channel-level option — `send-acks` — for sending "ack" control messages for each data frame we receive. At first, this new option supports a single value, `bytes`, which means to send ack messages with the number of bytes acknowledged. With this option enabled, the bridge will send: ``` {"command": "ack", "bytes": 16384} ``` for a received data frame containing 16384 bytes. The bridge is also free to combine acknowledgements (ie: the "bytes" field can be the sum from multiple messages). We can support this for all channels at the outset, even if the support is somewhat preliminary: if do_data() returns None (as it does for all existing channels) we send the acknowledgement immediately. Channels can decide to handle deferred sending on their own by returning True (which is a new possibility). We do that for AsyncChannel. The implementation for ProtocolChannel is sufficient if the bottleneck is the network upload speed but will fall over if the cause of throttling is the command (or socket) not accepting data. This is not going to be trivial to fix, and will be handled in a later version. Co-authored-by: Jelle van der Waa <jvanderwaa@redhat.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I like the Waiter
approach, that's quite explicit and easier to read. I only have one strong nack here about bringing back the "bigfile" upload test. The rest is totally ignorable noise. Cheers!
Introduces a helper function which handles uploading a ReadableStream to a server with `fsreplace1`, sending data in chunks, with proper flow control and progress reporting. This is made to be used for cockpit-files but is re-usable for other plugins. Add a React component to the playground as a proof of concept, and add a couple of integration tests based on it. Co-authored-by: Allison Karlitskaya <allison.karlitskaya@redhat.com>
2825145
to
7baa10f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me happy if bots are. Thanks for pushing this through and get past all our mutual bickering!
But please let @jelly review this as well, given how many sweat and emotions went in here 😅
if (window.debugging == 'all' || window.debugging?.includes('upload')) | ||
console.debug('upload', ...args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These 2 added lines are not executed by any test.
const handleClick = () => { | ||
if (ref.current) { | ||
ref.current.click(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These 3 added lines are not executed by any test.
<Alert variant={alert.variant} | ||
title={alert.title} | ||
timeout={3000} | ||
actionClose={<AlertActionCloseButton onClose={() => setAlert(null)} />} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test.
cb6da26
into
cockpit-project:main
upload()
) topkg/lib
to allow uploading large amounts of data (from aReadableStream
) using flow control, with progress reportingThis is my take on #20160