thread-synchronizationeclipse-rap

Eclipse RAP Multi-client but single server thread


I understand how RAP creates scopes have a specific thread for each client and so on. I also understand how the application scope is unique among several clients, however I don't know how to access that specific scope in a single thread manner.

I would like to have a server side (with access to databases and stuff) that is a single execution to ensure it has a global knowledge of all transaction and that requests from clients are executed in sequence instead of parallel.

Currently I am accessing the application context as follows from the UI:

synchronized( MyServer.class ) {
    ApplicationContext appContext = RWT.getApplicationContext();

    MyServer myServer = (MyServer) appContext.getAttribute("myServer");
        if (myServer == null){
          myServer = new MyServer();
          appContext.setAttribute("myServer", myServer);
        }
    myServer.doSomething(RWTUtils.getSessionID());
}

Even if I access myServer object there and trigger requests, the execution will still be running in the UI thread.

For now the only way to ensure the sequence is to use synchronized as follows on my server

public class MyServer {
    String text = "";

    public void doSomething(String string) {
        try {
            synchronized (this) {
                System.out.println("doSomething - start :" + string);
                text += "[" + string + "]";
                System.out.println("text: " + (text));
                Thread.sleep(10000);
                System.out.println("text: " + (text));
                System.out.println("doSomething - stop :" + string);
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Is there a better way to not have to manage the thread synchronization myself?

Any help is welcome

EDIT: To better explain myself, here is what I mean. Either I trust the database to handle multiple request properly and I have to handle also some other knowledge in a synchronized manner to share information between clients (example A) or I find a solution where another thread handles both (example B), the knowledge and the database. Of course, the problem here is that one client may block the others, but this is can be managed with background threads for long actions, most of them will be no problem. My initial question was, is there maybe already some specific thread of the application scope that does Example B or is Example A actually the way to go?

Eclipse RAP threads: how to handle shared knowledge and database access?

Conclusion (so far)

Basically, option A) is the way to go. For database access it will require connection pooling and for shared information it will require thoughtful synchronization of key objects. Main attention has to be done in the database design and the synchronization of objects to ensure that two clients cannot write incompatible data at the same time (e.g. write contradicting entries that make the result dependent of the write order).


Solution

  • First of all, the way that you create MyServer in the first snippet is not thread safe. You are likely to create more than one instance of MyServer.

    You need to synchronize the creation of MyServer, like this for example:

    synchronized( MyServer.class ) {
      MyServer myServer = (MyServer) appContext.getAttribute("myServer");
      if (myServer == null){
        myServer = new MyServer();
        appContext.setAttribute("myServer", myServer);
      }
    }
    

    See also this post How to implement thread-safe lazy initialization? for other possible solutions.

    Furthermore, your code is calling doSomething() on the client thread (i.e. the UI thread) which will cause each client to wait until pending requests of other clients are processed. The client UI will become unresponsive.

    To solve this problem your code should call doSomething() (or any other long-running operation for that matter) from a background thread (see also Threads in RAP)

    When the background thread has finished, you should use Server Push to update the UI.