Skip to content

Commit 98154e1

Browse files
fix: Cancel previous flush request if new one is forced (#14647) (#14699)
Fixes #14435 Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com>
1 parent 79c72e3 commit 98154e1

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

flow-data/src/main/java/com/vaadin/flow/data/provider/DataCommunicator.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,14 @@ private void requestFlush() {
10951095
private void requestFlush(boolean forced) {
10961096
if ((flushRequest == null || !flushRequest.canExecute(stateNode)
10971097
|| forced) && fetchEnabled) {
1098+
if (flushRequest != null) {
1099+
// this cancels the previous request pushed into the queue,
1100+
// because a new one is going to be registered forcibly to cover
1101+
// @PreserveOnRefresh cases. Otherwise two flush requests in the
1102+
// pending queue may lead to a infinite loop, generating more
1103+
// and more new requests.
1104+
flushRequest.setCancelled();
1105+
}
10981106
flushRequest = FlushRequest.register(stateNode, context -> {
10991107
if (!context.isClientSideInitialized()) {
11001108
reset();
@@ -1109,6 +1117,14 @@ private void requestFlush(boolean forced) {
11091117
private void requestFlushUpdatedData() {
11101118
if (flushUpdatedDataRequest == null
11111119
|| !flushUpdatedDataRequest.canExecute(stateNode)) {
1120+
if (flushUpdatedDataRequest != null) {
1121+
// this cancels the previous request pushed into the queue,
1122+
// because a new one is going to be registered forcibly to cover
1123+
// @PreserveOnRefresh cases. Otherwise two flush requests in the
1124+
// pending queue may lead to a infinite loop, generating more
1125+
// and more new requests.
1126+
flushUpdatedDataRequest.setCancelled();
1127+
}
11121128
flushUpdatedDataRequest = FlushRequest.register(stateNode,
11131129
context -> {
11141130
flushUpdatedData();
@@ -1478,22 +1494,29 @@ public static Activation empty() {
14781494
private static class FlushRequest implements Serializable {
14791495

14801496
private NodeOwner owner;
1497+
private boolean cancelled;
14811498

14821499
static FlushRequest register(StateNode stateNode,
14831500
SerializableConsumer<ExecutionContext> action) {
14841501
FlushRequest request = new FlushRequest();
14851502
request.owner = stateNode.getOwner();
14861503
stateNode.runWhenAttached(ui -> {
14871504
request.owner = stateNode.getOwner();
1488-
ui.getInternals().getStateTree().beforeClientResponse(stateNode,
1489-
action);
1505+
if (!request.cancelled) {
1506+
ui.getInternals().getStateTree()
1507+
.beforeClientResponse(stateNode, action);
1508+
}
14901509
});
14911510
return request;
14921511
}
14931512

14941513
boolean canExecute(StateNode stateNode) {
14951514
return owner instanceof NullOwner || owner == stateNode.getOwner();
14961515
}
1516+
1517+
void setCancelled() {
1518+
cancelled = true;
1519+
}
14971520
}
14981521

14991522
private static Logger getLogger() {

0 commit comments

Comments
 (0)