Skip to content

Transfer progress listener #21167

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

Open
mshabarov opened this issue Mar 20, 2025 · 0 comments
Open

Transfer progress listener #21167

mshabarov opened this issue Mar 20, 2025 · 0 comments

Comments

@mshabarov
Copy link
Contributor

mshabarov commented Mar 20, 2025

Describe your motivation

Vaadin Upload component has a list of upload progress listeners, but downloads have no ways to hook into download process, neither success nor failure hooks.
There should be a standard way for UI logic to react to progress, completion and premature termination of an upload or download.

Describe the solution you'd like

This is in the form of a TransferProgressListener that can be used directly from a handler or passed as an optional parameter to the handler factory methods. Methods related to observing progress in Upload that are based on StreamVariable callbacks are deprecated in favor of this new universal mechanism.

public interface TransferProgressListener {
  void onComplete(TransferContext context);
  void onTerminate(TransferContext context, IOException reason);
  long onProgress(TransferContext context, long transferredBytes, long totalBytes);
  long progressReportInterval(); // -1 to not report progress
}

The context object gives access to relevant common parts from the upload and download event types. In particular, there's access to the target element to deal with things like re-enabling a download button with disableOnClick enabled. We should probably define a shared base type for the events to make it easier to create a context object.

Nobody likes implementing interfaces with multiple methods since you cannot use lambdas. That's why we enhance the UploadHandler and DownloadHandler factory methods to return builders that allow chaining on progress listeners as lambdas.

// (should consider a shorter name)
// (same for DownloadHandler)
public interface UploadHandlerWithProgressSupport extends UploadHandler {
  static UploadHandlerWithProgressSupport whenComplete(
    Consumer<Boolean> completeOrTerminateHandler);
  static UploadHandlerWithProgressSupport onProgress(
    Consumer<Boolean> completeOrTerminateHandler,
    BiConsumer<Long, Long> progressHandler, long progressIntervalInBytes);
}

The boolean value is true if the transfer was successfully completed and false if terminated. We should maybe probably separate functional interfaces for these even though the shapes would be similar to the Consumer types shown here.

The easiest way of triggering the listener methods is through a helper method that transfers bytes from an InputStream to an OutputStream while reporting progress.

TransferProgressListener.transfer(inputStream, outputStream, uploadOrDownloadEvent, progressListener);
@mshabarov mshabarov moved this to 🪵Product backlog in Vaadin Flow ongoing work (Vaadin 10+) Mar 20, 2025
@mshabarov mshabarov changed the title [Draft] Transfer progress listener Transfer progress listener Mar 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🪵Product backlog
Development

No branches or pull requests

1 participant