Synchronization issues

I am currently developing an application which uses the “invisible progress indicator” hack to achieve server push functionality. Is there a way to know when the progress indicator is requesting a repaint? Adding repaint listener to progress indicator does not help, nor does overriding the paintContent method.

The problem is that the content to be pushed is generated in a separate thread, which eventually gets out of sync of the progress indicator’s polling interval. As a result the content is being generated at the same time when the content is being handled in CommunicationManager and this causes the following exception:

java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
	at java.util.AbstractList$Itr.next(AbstractList.java:343)
	at com.itmill.toolkit.terminal.gwt.server.CommunicationManager.getDirtyVisibleComponents(CommunicationManager.java:1151)
	at com.itmill.toolkit.terminal.gwt.server.CommunicationManager.paintAfterVariablechanges(CommunicationManager.java:396)
	at com.itmill.toolkit.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:309)
	at com.itmill.toolkit.terminal.gwt.server.ApplicationServlet.service(ApplicationServlet.java:445)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
...

How this could be fixed? Some suggestions:

  1. Add a possibility to add a listener to ProgressIndicator which would be called when client contacts the server. This may have some performance issues, but typically server-push hacks are used in systems which aren’t meant for large number of users anyway.

  2. Make the handling of dirtyPaintabletSet thread-safe in the CommunicationManager class. Actually, I added synchronization blocks to relevant places in CommunicationManager. As the result the exceptions are gone and everything in my application works perfectly.

Example where synchronization is needed in CommunicationManager (line ~1133):


    private ArrayList getDirtyVisibleComponents(Window w) {
        synchronized (dirtyPaintabletSet) {
            final ArrayList resultset = new ArrayList(dirtyPaintabletSet);
            ...

-Jukka

FYI: the message above is written by me, I forgot to login when posting it…

-Jukka

Hi Jukka!

Try making you changes to Toolkit application (in your separate thread) in a synchronized block using application instance as a lock. I’d guess it will resolve your concurrency issues as server visits are also synchronized with the same lock.

cheers,
matti