How to refresh other users Vaadin Table without causing Concurrent Modification Exception?

2.3k Views Asked by At

Use Case: User logged in and a Vaadin Table component opened showing statuses of appointments. Every row has a drop down (ComboBox) to change status (Scheduled, Arrived, Reviewed). Now multiple users has opened this table in their own browsers and making continuous changes to appointment status. These changes should be reflected on all opened tables i.e if user A changes status of appointment appt-1 it reflects and refresh on all Tables currently opened.

Previously we applied event based refreshing with ICE-PUSH Add-on i.e if Change made on PC-1 (i.e Application instance a1), i get the other instances of Vaadin application from static CopyOnWriteArrayList from MainApplication class and by that instance I call loadTable function. after that I call the ICEPUSH to push new changes to all users.

public class MainApplication extends Application {
    public static CopyOnWriteArrayList<MainMedMaxApplication> appList=new CopyOnWriteArrayList<MainMedMaxApplication>();

    @Override
    public void init() {
        setMainWindow(new Window("APPointment Dashboard"));
        getMainWindow().setContent(mainLayout);
        setMainComponent(getCustomTable());
        //Custome Table make table . it also register listeners over table.
        //loadTable will load the table. 
        loadTable()
        appList.add(this);  
    } 
}

public void loadTabl(String date) {
    //this will reload the table component By Querying database
}
private void registerlistener() {
    table.addListeners()
        {
        //do any change to table in this instance and save it to db then call ICE push so it can referesh all app instances by getting from applist.
        synchronizePortlets();
        }
}
public void synchronizePortlets() {
    // TODO Auto-generated method stub
    Iterator<MainApplication>itM = appList.iterator();
    while(itM.hasNext()) {
        MainApplication app = itM.next();
        app.loadTabl();
        app.getPusher().push();
    }
}
}

This works fine but in some conditions when to many frequent changes made then Concurrent Modification Exception rises. so if any one can help to improve this?

The solution I am thinking after this is to refresh table component not forcefully rather continuously in every 1 mint by its own app instances. This will query database and reload the table container with updated statuses. For this purpose I use Refresher add-on But it raises an exception i.e ConcurrentModificationException, because sometimes user also changing the table component by changing combo statuses in table meanwhile refresher refresh the Table and here raises concurrent Modification exception. So I am thinking of freezing Table component from user point of view so user can't do anything and in background can easily refresh table.

If for this use case you guys have better solution please do tell me. I am grateful of you.

Using Vaadin 6.8.12, java 1.7, apache Tomcat 7.42

1

There are 1 best solutions below

3
On

Vaadin 6

You need to apply synchronization since you're making changes to the GUI from another thread (and I think it doesn't matter whether Refresher or IcePush is used, I think in both cases you'll use another thread). Synchronize on the Application instance.

See this post on the Vaadin forum.

Vaadin 7

EDIT: I encourage you to upgrade to Vaadin 7.1 and use this new method on UI: UI#access as is recommended here.