flow-components icon indicating copy to clipboard operation
flow-components copied to clipboard

Changes done in a StartedListener are not shown

Open Artur- opened this issue 7 years ago • 6 comments
trafficstars

Upload upload = new Upload();
upload.addStartedListener(e -> {
    add( new Text("Upload of " + e.getFilename() + " of size " + e.getContentLength() + " started"));
        });

When the upload starts, no text is shown. When the upload is abort or completed, the text is shown.

Artur- avatar Jan 24 '18 13:01 Artur-

This probably means that the listener is run without access and might thus also cause other interesting issues.

Legioth avatar Jan 25 '18 06:01 Legioth

All events are fired and handled by the listeners correctly on the server side: all locks and access are done properly. The listener code on the server side is executed at the correct time. The problem is that the listener in this specific case produces some changes in the StateTree instance. Those changes are sent to the client only in the end of the response handling. But the input stream is read in the same request dispatching thread so nothing will be sent to the client until stream is completely read. That's the reason why all listeners shows their result in the very end (on the client side). Though on the server side they are called at the correct time.

denis-anisimov avatar Apr 25 '18 07:04 denis-anisimov

@denis-anisimov Upload should make a visit to server once a file is submitted. This is how previous Vaadin versions worked. Without that, the started listener is almost useless (unless using Push, which I presume "fixes" the issue).

Here is a simple code snippet to test this locally with small files:

    Upload upload = new Upload((MultiFileReceiver) new MultiFileReceiver() {
        @Override
        public OutputStream receiveUpload(String filename, String mimeType) {
            return new OutputStream() {
                int count;

                @Override
                public synchronized void write(int b) {
                    count++;
                    if(count%10 == 0) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            };
        }
    });
    upload.addStartedListener(e -> {
        System.out.println("Handling upload of " + e.getFileName() + " ("
                + e.getContentLength() + " bytes) started");
        Notification.show("This message should pop up when upload has started");
    });
    upload.addFinishedListener(e -> {
        System.out.println("Handling upload of " + e.getFileName() + " ("
                + e.getContentLength() + " bytes) finished");
    });
    upload.addSucceededListener(e -> {
        System.out.println("Handling upload of " + e.getFileName() + " ("
                + e.getContentLength() + " bytes) succeeded");
        Notification.show("This message should pop up when upload has succeeded");
        
    });

mstahv avatar Jan 04 '19 13:01 mstahv

So we'd need something like this to V10+ too:

https://github.com/vaadin/framework/blob/master/client/src/main/java/com/vaadin/client/ui/VUpload.java#L295-L317

mstahv avatar Jan 04 '19 13:01 mstahv

We faced a similar issue (if I understood it correctly), we wanted to disable the buttons while the upload was in progress (right after the upload starts). We used the following workaround and it worked:

uploadComponent.getElement().addEventListener("upload-start",e -> disableButtons());

mlopezFC avatar Mar 26 '24 20:03 mlopezFC

This is indeed an annoying bug. In our case we have a start listener that sets a flag when an upload is started and an all-finished listener that clears it again. The flag is evaluated in a dialog's validation before a final action is triggered.

This currently doesn't work if e.g. a large file (1GB in our case) is uploaded - the flag is only set when the large upload finishes.

Note: We have tried to leverage Upload::isUploading field for the same use case, but this one isn't updated either until all uploads are done (the listener approach at least works if there are smaller files contained in a multifile upload).

@mlopezFC thanks alot for the workaround.

cmrg-chb avatar May 16 '24 15:05 cmrg-chb