summaryrefslogtreecommitdiffstats
path: root/server/src/com
diff options
context:
space:
mode:
authorSauli Tähkäpää <sauli@vaadin.com>2014-03-21 09:30:46 +0000
committerVaadin Code Review <review@vaadin.com>2014-03-21 09:30:46 +0000
commita70ef27bb7b6e8c41a27041bdd1b794c95544be8 (patch)
treef4670325e3f8237998f987516ac226cf5b9161dc /server/src/com
parent44f3ea58cd7bdca7e25d92b6c411da58d9928e6c (diff)
parent1f149be0e8c49e8d7a69853f758f2a01356202e5 (diff)
downloadvaadin-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.java49
-rw-r--r--server/src/com/vaadin/ui/UI.java13
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;