4

I am facing a problem in understanding following quote of VaadinSession.getCurrent()

Gets the currently used session. The current session is automatically defined when processing requests to the server and in threads started at a point when the current session is defined (see InheritableThreadLocal). In other cases, (e.g. from background threads started in some other way), the current session is not automatically defined.

Specifically following point is difficult to understand for me,

... in threads started at a point when the current session is defined (see InheritableThreadLocal).

What does that mean ?

My understanding is if thread is created before the new Session has been defined or in the old session then it will not refer to the current newly created Session.

Currently I have Thread Pool and some threads are referring to the old session which is now closed then I will face the problem in using session in those threads.

I'm using spring with vaadin, specifically @Async method calls.

@Async
public static methodX() {
    //I have used session inside it
}

Problem is say, thread1 has been used to execute methodX, now I have used session session1 and after the user logout this session1 will be closed.

Now, when new user logs in to the system which has session2 and executes this method with thread1 again then this method has still used session1 instead of session2 and that creates problem when methods tries to fetch data from the closed session1.

My Questions :

  • Why Vaadin can not provide or notify old threads (i.e. threads which belongs to the old(closed) session) about the newly defined Session ?
  • What is the best way to provide the session to these threads ?
akash
  • 22,664
  • 11
  • 59
  • 87

2 Answers2

3

It means that if you are processing data in separate threads, you will not have the current session :

So this code :

Runtime runtime = Runtime.getRuntime();                 
final Process process = runtime.exec(action);
new Thread() {
    public void run() {
        try {
            System.out.println(VaadinSession.getCurrent());
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}.start();

inside your vaadin project will print an old session, the one you had when the Thread has been started.

Edit

I think Vaadin can not provide new session to old threads to avoid data corruption problems. I mean if 5 Threads are editing the same session, you will have a problem...

The solution for you is to provide Session to every threads in your pool but I really don't know how to achieve this, and Google did not give me the answer so far.

Edit : Another possible solution

Create a class to store every Sessions (using SessionListener) using a HashMap<int, VaadinSession> in a static way.

When you create your threads, give them the id of the session they need to use (id is the key corresponding to your the session you want in the HashMap). And then every time a session is edited, destroyed etc, simply edit it in the HashMap.

Because of the static behavior of this HashMap, you'll be able to access it from any threads at any time, the only thing you will need is the int id corresponding to your session in the thread.

Community
  • 1
  • 1
Supamiu
  • 8,501
  • 7
  • 42
  • 76
  • Your answer is not clear to me. Can you please add more info ? I mean in your answer you have not used *process* anywhere and apart from that I am able to get current Session by declaring `new Thread` in my project. Only problem is some threads of *pool* are referring to the old session. – akash Sep 07 '15 at 14:36
  • I edited my answer to match your comment, in fact I made a mistake yes, you will not get a null Session, you will get an old one. Problem is that you can not pass variables through multiple Threads, the only solution can be to create a static Map or array to store Sessions and update them, then from the Thread you can get an updated session using its ID. I'll update answer to add this soon. – Supamiu Sep 07 '15 at 15:11
0

Problem is for background threads the VaadinSession(not to be confuse with HttpSession) is not available. After searching for this in book of vaadin I came to the conclusion with following solution.

To get current session we have VaadinSession.getCurrent() and UI.getCurrent().getSession() both of them returns the session.

Problem is old threads which are created during some other session are unable to access the current session as already stated in quote. This situation only raised with the @Async calls.

@Async
public void method() {
   //get id from session
}

Once application gets loaded the method can be used by multiple vaadin requests and each time thread of ThreadPool executes the task.

Thread - 1 executed method - used session 1
session 1 closed
session 2 defined
Thread - 1 again used to execute method
Thread - 1 executed method - used session 1 instead of new defined session 2

Now, in my case for each vaadin request we have new UI instance. But the UI the old thread was considering was obsolete for which session is closed.

I have externally passed the UI instance to this asynchronous method, like this.

@Async
public void method(UI ui) {
   UI.setCurrent(ui);
   UI.getCurrent().getSession();//Now I have latest session
}

It was also stated in the documentation of UI.setCurrent(UI ui) method,

The application developer can also use this method to define the current UI outside the normal request handling, e.g. when initiating custom background threads.

akash
  • 22,664
  • 11
  • 59
  • 87