diff options
author | Build Agent <build@vaadin.com> | 2014-03-21 10:29:58 +0200 |
---|---|---|
committer | Build Agent <build@vaadin.com> | 2014-03-21 10:29:59 +0200 |
commit | 1f149be0e8c49e8d7a69853f758f2a01356202e5 (patch) | |
tree | 17bd83f8579ca996a3382c27b186a6a866fdd9b5 /server/src/com | |
parent | d90416ce1bf53b18e14b951e27f36d7323b3f3d3 (diff) | |
parent | e45294f717f920a6dfbcf36aff68d25d9b00cca3 (diff) | |
download | vaadin-framework-1f149be0e8c49e8d7a69853f758f2a01356202e5.tar.gz vaadin-framework-1f149be0e8c49e8d7a69853f758f2a01356202e5.zip |
Merge changes from origin/7.1
7112abe Preventing premature start of drag due to Chrome move event #13381
7e7b623 reduce frequency of session locking and StreamingProgressEvents (#13155)
7cab7fd Improve error message when reusing UI instance (#13457)
3e53fa6 Fixed "EEE" in DateField's date pattern (#13443)
1881ea8 Fix for width issue of TabSheet (#12805)
396820e Test for streaming reconnect issue (#13435)
2f93186 Eliminate .v-caption memory leak (#13346)
0c7cbc7 Fixes a memory leak on IE8 in LayoutManagerIE8 (#12688)
5441ef0 Merged IntegrationTestRunner into TB3Runner
3545db2 Added User-Agent and Screen Width + Height labels to portlet test.
c5aaf93 Refactored JSR286 portlet test.
52dcbaa Pressing ESC now closes the DateField popup when using month or year resolutions. (#12317)
e45294f Revert "Preventing premature start of drag due to Chrome move event #13381"
Change-Id: I35e119a6e8e68e226487906af35eaa220f3af16f
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; |