Background thread get UI data

Hi all, i’ve been working with doing some background data tasks and updating the UI asyncronously, though I have a few session attributes that I need to access from methods which are called by the background thread. I just wanted to make sure what i’m doing was sane, and not going to cause any problems later on.

The worker class is as such:

private final class BgWorker extends Thread
{
    private final UI ui;

    public BgWorker(final UI ui)
    {
        this.ui = ui;
    }

    @Override
    public void run()
    {
        try 
        {
            UI.setCurrent(this.ui);
            //do work... call other methods which will be
            //calling UI.getCurrent().getSession().getAttribute("something");
        }
        catch(Exception x)
        {}
        finally
        {
            UI.setCurrent(null);
        }
    }
}

From the UI thread, I add the above to my threadpool and instanciate it like so:

ThreadPool.INSTANCE.executeTask(new BgWorker(UI.getCurrent()));

This is seemingly working as intended now, and able to get the correct session when calling UI.getCurrent.getSession() (prior to setting the UI, that did not return the correct session), but I wanted to check with the experts and make sure there won’t be anything unintended.

Does the setCurrent(ui) add the given UI instance for the specific thread invoking the method? And if so, does invoking setCurrent(null) inside the thread remove the thread from the internal list maintained by Vaadin?

Thanks,
-Adam

Hi Adam,

Your code is not thread safe as it does not lock the VaadinSession before accessing the UI. The preferred pattern is using the UI.access and VaadinSession.access methods as described in
Book of Vaadin section 11.16.3
. Inside an access block Vaadin automatically sets the relevant threadlocals in addition to properly handling session locking.

I do use UI.getCurrent().access() within my thread for any updates to the UI, it just wasn’t part of the question so I didn’t include that code in my example. What is this about VaadinSession.access() though? Is that how I should be accessing any session variables instead of: UI.getCurrent().getSession().getAttribute(“something”);?

If so, I suppose that also means that just UI.setCurrent() in the background thread isn’t enough, and i’d also have to utilize VaadinSession.setCurrent()?

Edit: Never mind, I understand how this works now. Yeah, for the data processing portion I really don’t need a lock on the session. I just need to make sure i’ve done UI.setCurrent when entering my thread, because I have objects which depend on their return values from that session variable.
I pretty much use the session to store an account id that the user is logged in as, and when I need to contextualize the page, I must use that ID to retrieve the correct account instance. That same account id is also used when making database calls though, as I need to make sure the data is contextualized to the specific user. That is what I was doing in that thread above, making a call to the DB, which required the thread return the correct session’s attributes when calling UI.getCurrent().getSession().

Hmm… All right.

So you want to access session attributes without synchronization? I’m afraid this is not guaranteed to be safe either; indeed, if you have assertions enabled, VaadinSession.getAttribute() will fail noisily unless the session is locked. If I understood your use case correctly, you should probably store the relevant data as variables in your BgWorker class and possibly set your own threadlocals in BgWorker.run() if you don’t want to pass them manually to whatever’s doing the actual work.