Long synchronous operation block other UIs

Hello!

I have an application that starts a long synchronous operation. The users see a blue loading indicator at the top of the application. When they close the frozen browser tab and open a new one with the app, it is not loaded until the operation is complete.

I know that the operation can be started in a background thread, but I wonder why this happens. I found out that the SynchronizedRequestHandler blocks the VaadinSession before performing the request. Is there a reason to block the session? How can I avoid this behavior and not use background threads?

Why don’t you want to use a thread?

When they close the frozen browser tab and open a new one with the app, it is not loaded until the operation is complete.

This is because the request-handling thread that does the long-running operation still holds the session lock. Sessions are locked to protect the UI state and various framework-internal bookkeeping from corruption that might happen if updated from multiple threads at the same time.

The lock could in theory be per UI instance instead of per session but it’s not built in that way for historical reasons and changing it at this point would not be practical due to the amount of existing application code that expects it to be like it is now.

How can I avoid this behavior and not use background threads?

This is what threads are meant for: allow doing multiple things in parallel. If you’re concerned by the overhead of starting new OS threads, then you can use a thread pool or virtual threads (introduced in Java 21).

2 Likes

Yes, I would use threads, but in my application, there is a third-party code that can perform a long task and access the UI at the end.

Thank you for the answers! Do you have plans to implement blocking UI, perhaps in the far future? Maybe you have an issue in the GitHub repository?

It doesn’t hurt to create a ticket in the Flow repository. We don’t have plans for making this type of change for the moment but we do keep any eye on how many :+1: reactions there are on all issues and use that as one input for prioritizing improvements.

Please read Server Push | Advanced Topics | Flow | Vaadin Docs

Yes, I would use threads, but in my application, there is a third-party code that can perform a long task and access the UI at the end.

That’s exactly what you can do with push and ui.access (See the link from Simon)

Thanks for the provided link. I use ui.access() where it is possible.

Just to clarify what I meant:

  • The application has third-party code that uses UI elements. If I run this code in a separate thread, it will lead to:
IllegalStateException: Cannot access state in VaadinSession or UI without locking the session.

What is the third party? It seems to use Vaadin. But normally you shouldn’t need to block the Vaadin session for a long time.

My guess would be this Long operation in UI freezes all other UIs even after closing a browser tab · Issue #3550 · jmix-framework/jmix · GitHub

1 Like

I created a feature request. Here is the link if anyone is interested: Block UI instance per request-handling thread · Issue #19785 · vaadin/flow · GitHub

The piece of blocking call where do you have it?

The error you got above is because a component of “vaadin” is not protected correctly with the access method.

IllegalStateException: Cannot access state in VaadinSession or UI without locking the session.

As of today you can fix it 100%.

It would be nice if you could show at least a minimal piece of code.

Surely it is not a Vaadin Flow issue.