diff options
author | Sauli Tähkäpää <sauli@vaadin.com> | 2014-03-21 09:30:46 +0000 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2014-03-21 09:30:46 +0000 |
commit | a70ef27bb7b6e8c41a27041bdd1b794c95544be8 (patch) | |
tree | f4670325e3f8237998f987516ac226cf5b9161dc /server/src/com | |
parent | 44f3ea58cd7bdca7e25d92b6c411da58d9928e6c (diff) | |
parent | 1f149be0e8c49e8d7a69853f758f2a01356202e5 (diff) | |
download | vaadin-framework-a70ef27bb7b6e8c41a27041bdd1b794c95544be8.tar.gz vaadin-framework-a70ef27bb7b6e8c41a27041bdd1b794c95544be8.zip |
Merge "Merge changes from origin/7.1"
Diffstat (limited to 'server/src/com')
-rw-r--r-- | server/src/com/vaadin/server/communication/FileUploadHandler.java | 49 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/UI.java | 13 |
2 files changed, 48 insertions, 14 deletions
diff --git a/server/src/com/vaadin/server/communication/FileUploadHandler.java b/server/src/com/vaadin/server/communication/FileUploadHandler.java index 41a16601fe..dc397eadcd 100644 --- a/server/src/com/vaadin/server/communication/FileUploadHandler.java +++ b/server/src/com/vaadin/server/communication/FileUploadHandler.java @@ -227,6 +227,9 @@ public class FileUploadHandler implements RequestHandler { /* Same as in apache commons file upload library that was previously used. */ private static final int MAX_UPLOAD_BUFFER_SIZE = 4 * 1024; + /* Minimum interval which will be used for streaming progress events. */ + public static final int DEFAULT_STREAMING_PROGRESS_EVENT_INTERVAL_MS = 500; + @Override public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { @@ -550,26 +553,35 @@ public class FileUploadHandler implements RequestHandler { } final byte buffer[] = new byte[MAX_UPLOAD_BUFFER_SIZE]; + long lastStreamingEvent = 0; int bytesReadToBuffer = 0; - while ((bytesReadToBuffer = in.read(buffer)) > 0) { - out.write(buffer, 0, bytesReadToBuffer); - totalBytes += bytesReadToBuffer; + do { + bytesReadToBuffer = in.read(buffer); + if (bytesReadToBuffer > 0) { + out.write(buffer, 0, bytesReadToBuffer); + totalBytes += bytesReadToBuffer; + } if (listenProgress) { - // update progress if listener set and contentLength - // received - session.lock(); - try { - StreamingProgressEventImpl progressEvent = new StreamingProgressEventImpl( - filename, type, contentLength, totalBytes); - streamVariable.onProgress(progressEvent); - } finally { - session.unlock(); + long now = System.currentTimeMillis(); + // to avoid excessive session locking and event storms, + // events are sent in intervals, or at the end of the file. + if (lastStreamingEvent + getProgressEventInterval() <= now + || bytesReadToBuffer <= 0) { + lastStreamingEvent = now; + session.lock(); + try { + StreamingProgressEventImpl progressEvent = new StreamingProgressEventImpl( + filename, type, contentLength, totalBytes); + streamVariable.onProgress(progressEvent); + } finally { + session.unlock(); + } } } if (streamVariable.isInterrupted()) { throw new UploadInterruptedException(); } - } + } while (bytesReadToBuffer > 0); // upload successful out.close(); @@ -612,6 +624,17 @@ public class FileUploadHandler implements RequestHandler { return startedEvent.isDisposed(); } + /** + * To prevent event storming, streaming progress events are sent in this + * interval rather than every time the buffer is filled. This fixes #13155. + * To adjust this value override the method, and register your own handler + * in VaadinService.createRequestHandlers(). The default is 500ms, and + * setting it to 0 effectively restores the old behavior. + */ + protected int getProgressEventInterval() { + return DEFAULT_STREAMING_PROGRESS_EVENT_INTERVAL_MS; + } + static void tryToCloseStream(OutputStream out) { try { // try to close output stream (e.g. file handle) diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index e688c06061..b3004e9ad2 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -613,7 +613,18 @@ public abstract class UI extends AbstractSingleComponentContainer implements */ public void doInit(VaadinRequest request, int uiId, String embedId) { if (this.uiId != -1) { - throw new IllegalStateException("UI id has already been defined"); + String message = "This UI instance is already initialized (as UI id " + + this.uiId + + ") and can therefore not be initialized again (as UI id " + + uiId + "). "; + + if (getSession() != null + && !getSession().equals(VaadinSession.getCurrent())) { + message += "Furthermore, it is already attached to another VaadinSession. "; + } + message += "Please make sure you are not accidentally reusing an old UI instance."; + + throw new IllegalStateException(message); } this.uiId = uiId; this.embedId = embedId; |