Skip to content

Nested calls to UI.beforeClientResponse and UI.access result in multiple pushes #21098

@mperktold

Description

@mperktold

Description of the bug

When a listener calls UI.beforeClientResponse and UI.access in a nested way, each pair of those will trigger a separate push message. This is not wrong per se but unexpected and could lead to performance issues.

This behavior comes from here:

getService().ensureAccessQueuePurged(this);

This line makes sure that additional calls to UI.beforeClientResponse and UI.access are pushed to the client immediately and not only on the next push. However, it does so in separate push messages instead of collecting all changes into one push message.

In our project, we have some code that calls Dialog.open, which attaches the dialog to the UI using UI.beforeClientResponse. Inside the attach handler of the dialog component, some code called UI.access for whatever reason. While investivating some other problem, we noticed in some logs that there where a lot of push messages (like 8 per second). We then found out that the mechanism described in this issue was the reason for some of them.

Expected behavior

A call to UI.push (or VaadinSession.unlock) should collect all changes into one message instead of sending a separate push for each nested call.

Minimal reproducible example

public class PushTest extends VerticalLayout {
 
    public PushTest() {
        UI ui = UI.getCurrent();
        add(new Button("notify", e -> {
            Notification.show("listener");
            ui.beforeClientResponse(this, ctx1 -> {
                ui.access(() -> {
                    Notification.show("nested 1");
                    ui.beforeClientResponse(this, ctx2 -> {
                        ui.access(() -> {
                            Notification.show("nested 2");
                        });
                    });
                });
            });
        }));
    }
}
  1. Open this view in the browser with the network tab open in the DevTools.
  2. Select the push websocket request. If you can't see it, refresh the page.
  3. Click on the "notify" button.
  4. You will see 2 push messages for every click.

Versions

  • Vaadin / Flow version: 24.6.6
  • Java version: OpenJDK 64-Bit Server VM Temurin-21.0.6+7 (build 21.0.6+7-LTS, mixed mode, sharing)
  • OS version: Windows 11

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    🔖 Low Priority (P3)

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions