Skip to content

Commit bbb93aa

Browse files
committed
WIP
1 parent d60c653 commit bbb93aa

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

src/main/java/com/flowingcode/vaadin/addons/gridexporter/ConcurrentStreamResourceWriter.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.flowingcode.vaadin.addons.gridexporter;
22

3+
import com.vaadin.flow.component.UI;
34
import com.vaadin.flow.server.StreamResourceWriter;
45
import com.vaadin.flow.server.VaadinSession;
56
import java.io.IOException;
67
import java.io.InterruptedIOException;
78
import java.io.OutputStream;
89
import java.nio.channels.InterruptedByTimeoutException;
10+
import java.util.Optional;
911
import java.util.concurrent.Semaphore;
1012
import java.util.concurrent.TimeUnit;
1113
import java.util.function.IntFunction;
@@ -147,6 +149,22 @@ public float getCost(VaadinSession session) {
147149
return DEFAULT_COST;
148150
}
149151

152+
/**
153+
* Returns the UI associated with the current download.
154+
* <p>
155+
* This method is used to ensure that the UI is still attached to the current session when a
156+
* download is initiated. Implementations should return the appropriate UI instance.
157+
* </p>
158+
*
159+
* @return the {@link UI} instance associated with the current download, or {@code null} if no UI
160+
* is available.
161+
*/
162+
protected abstract UI getUI();
163+
164+
private UI getAttachedUI() {
165+
return Optional.ofNullable(getUI()).filter(UI::isAttached).orElse(null);
166+
}
167+
150168
/**
151169
* Callback method that is invoked when a timeout occurs while trying to acquire a permit for
152170
* starting a download.
@@ -181,15 +199,19 @@ public final void accept(OutputStream stream, VaadinSession session) throws IOEx
181199
} else {
182200

183201
try {
184-
185202
int permits;
186203
float cost = getCost(session);
187204
synchronized (semaphore) {
188205
permits = costToPermits(cost, semaphore.maxPermits);
189206
}
190207

208+
UI ui = getAttachedUI();
209+
191210
if (semaphore.tryAcquire(permits, getTimeout(), TimeUnit.NANOSECONDS)) {
192211
try {
212+
if (ui != null && getAttachedUI()!=ui) {
213+
throw new DetachedIOException();
214+
}
193215
delegate.accept(stream, session);
194216
} finally {
195217
semaphore.release(permits);

src/main/java/com/flowingcode/vaadin/addons/gridexporter/GridExporter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.flowingcode.vaadin.addons.fontawesome.FontAwesome;
2323
import com.flowingcode.vaadin.addons.gridhelpers.GridHelper;
2424
import com.vaadin.flow.component.ComponentUtil;
25+
import com.vaadin.flow.component.UI;
2526
import com.vaadin.flow.component.grid.ColumnPathRenderer;
2627
import com.vaadin.flow.component.grid.Grid;
2728
import com.vaadin.flow.component.grid.Grid.Column;
@@ -336,6 +337,11 @@ public long getTimeout() {
336337
return concurrentDownloadTimeoutNanos;
337338
}
338339

340+
@Override
341+
protected UI getUI() {
342+
return grid.getUI().orElse(null);
343+
}
344+
339345
@Override
340346
protected void onTimeout() {
341347
fireConcurrentDownloadTimeout();

src/test/java/com/flowingcode/vaadin/addons/gridexporter/ConfigurableConcurrentStreamResourceWriter.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.flowingcode.vaadin.addons.gridexporter;
22

3+
import com.vaadin.flow.component.UI;
34
import com.vaadin.flow.server.StreamResourceWriter;
45
import com.vaadin.flow.server.VaadinSession;
56

@@ -13,6 +14,7 @@ public ConfigurableConcurrentStreamResourceWriter(StreamResourceWriter delegate)
1314

1415
private float cost = GridExporter.DEFAULT_COST;
1516
private long timeout = 0L;
17+
private UI ui;
1618

1719
@Override
1820
public float getCost(VaadinSession session) {
@@ -32,4 +34,13 @@ public void setTimeout(long timeout) {
3234
this.timeout = timeout;
3335
}
3436

37+
@Override
38+
public UI getUI() {
39+
return ui;
40+
}
41+
42+
public void setUi(UI ui) {
43+
this.ui = ui;
44+
}
45+
3546
}

0 commit comments

Comments
 (0)