How to find out what is causing "Out of sync"?

Hello,

I’m getting red “Out of sync” box on top of my application in some situations.
Also I get “Warning: Ignoring variable change for non-existent component, VAR_PID=PID150” into server console.

To solve this specific problem, it might be good to present some code which is causing it… Instead, I would prefer to get some knowledge of how to find/debug root of this error.

(FYI: I created simplified code example of my complex application which has “Out of sync” issue, but this example didn’t produce any errors… So, it means I’m doing something wrong on my complex application, just would like to know how can I find the hot spot.)

Hi,

Is “in some situations” a specific situation that you can reproduce, or does it occur seemingly at random?

Could restarting the server, and opening/closing windows or tabs have something to do with the problem? (I have a theory, and I’m investigating one possible out-of-sync cause, that could occur - especially during development)

To investigate, keep an eye on the traffic between server/client, and figure out which component has a variable w/ PID150. In practice, this variable has existed earlier, but has been removed (component removed, for instance), and the client still tries to send a variable change to the non-existing variable. This should never happen.

Best Regards,
Marc

Hi,

Sorry for unclear explanation… By “in some situations” I didn’t mean I get this error randomly, I get it always when I do certain process. But I do get it at seemingly different situations, thus “in some”.

This was what I wanted to hear, thanks for help :slight_smile:

Hi,

Thanks again Marc for help, I got into track of whats going on…

On some views of my application, I have action menu which act as kind of short cut to different tasks (opening different views). Opening new view works like it should, but problem comes when I have this action menu in view (top of it) - it gets removed along with old view when new one is opened. It don’t matter if I keep old view in viewStack or let it go to garbage collecting, result is still the same.

This action menu is implemented extending PopupView.

“Out of sync” comes when client sends “722720falsePID21popupVisibilityb” to server (looking this from console of FireFox).

What should I do with this message? Can it be ignored somehow as its not needed anymore (as view which has this popup is not showing anymore). Or is there some other way to prevent it?

The problem is that you add PopupView to a layout, and then remove the layout when the clientside popup is still visible. Then when the clientside popup is hidden, it tries to send tell the server that it is hidden, but the component has already been removed. I think the popup should be hidden if the component is removed serverside. I’ll make a ticket for this. A workaround would be to have the PopupView on a different layout, but this is not possible in all cases.

Hi,

Thanks for tip Risto:

I tried this with code below, but I still get “Out of sync”. Can you check if I have written hiding properly - seems that calling setVisible(false) wont help here.

public class MyApplication extends Application {

	private GridLayout baseLayout;

	public void init() {
		Window main = new Window("PopupView test");
	        setMainWindow(main);

	        baseLayout = new GridLayout(1, 2);
	        baseLayout.setSizeFull();
	        
	        HorizontalLayout header = new HorizontalLayout();
	        header.addComponent(new Label("Header"));
	        baseLayout.addComponent(header, 0, 0);
	        
	        main.setLayout(baseLayout);

	        setView(createView("HOME"));
	}
	
	public HorizontalLayout createView(String caption){
		HorizontalLayout horizontalLayout = new HorizontalLayout();
		horizontalLayout.addComponent(new Label(caption));
	        ActionsPanel ap = new ActionsPanel();
	        horizontalLayout.addComponent(ap);
	        return horizontalLayout;
	}

	public void setView(HorizontalLayout view){
	        baseLayout.removeComponent(0, 1);
	        baseLayout.addComponent(view, 0, 1);
	}

	public class ActionsPanel extends PopupView implements PopupView.Content, ClickListener {

		private Component currentComponent;
		private Button button1;
		
		public ActionsPanel() {
			//set initial content to something...Cannot be null
			super(new PopupView.Content() {
				public String getMinimizedValueAsHTML() { return ""; }
				public Component getPopupComponent() { return new Label(""); }
			});

	        VerticalLayout layout = new VerticalLayout();
	        layout.setWidth("400px");
	        layout.setHeight("200px");

			button1 = new Button("Button1");
			button1.addListener(this);
	        layout.addComponent(button1);

			currentComponent = layout;
			setContent(this);
			setHideOnMouseOut(false);
		}

		public String getMinimizedValueAsHTML() {
			return "<div class=\"actionspanel\">" +
						"<div class=\"actionspanel-text\">ACTIONS</div>" +
						"<div class=\"actionspanel-button\">&nbsp;</div>" +
				   "</div>";
		}

		public Component getPopupComponent() {
			return currentComponent;
		}
		public void setLayoutComponent(Component newComponent) {
		    currentComponent = newComponent;
		}

		public void buttonClick(ClickEvent event) {
			if(event.getButton() == button1){
		        setView(createView("popup created view"));
			}
			// Attempt to set popup invisible
			this.setVisible(false);
		}
	}
}

Sorry, I wrote my answer in a hurry. What I meant, was that the component should automatically hide itself when it is removed. This is a bug. setVisible() doesn’t work correctly either because PopupView was not meant to be hidden by the server. I created a ticket for the issue:
http://dev.itmill.com/ticket/2436

I’ll try to fix this asap. In the meanwhile, you can either use the PopupView in a layout that isn’t removed, or just hide/show the views instead of removing/adding them.

Hi Risto (and any GWT enabled),

I think I’ve something similar, while not exactly the same. Maybe you could help me to understand. My application uses vaadin-6.1-pre2.

I use the SuperImmediateTextField from Henrik. On the client side, VSuperImmediateTextField has a Timer (a thread) that fires events.

While the timer is counting, I server-side remove the SuperImmediateTextField from its layout and leave it for garbage collection.
A few seconds later, the Firebug consoles shows me an event sent from VSuperImmediateTextField. Of course, the server side component does not exist aymore. I get the warning,

Warning: Ignoring variable change for non-existent component, VAR_PID=PID1493

and the out of sync message as response.

I don’t understand why, when I call .removeAllComponents() on the containing layout, the client side VSuperImmediateTextField is still alive. Or maybe is the VSuperImmediateTextField not active, but it’s timer (separate object) well? How could the timer detect, “oh, the server side component does not exist anymore, I should not fire the last event” ?

Many thanks.
John.

Hi. Having no experience whatsoever on the SuperImmediateTextField, you could try adding something like

    @Override
    protected void onDetach() {
        timer.cancel();
        super.onDetach();
    }

in the client-side code?

Thank you Risto, it works.

I learned something thanks to you.

So this is a bug in SuperImmediateTextField? Henrik - would you like to commit this as a fix to SVN?

Sorry about that! I’ve now committed the fix Risto so helpfully figured out on my behalf to the svn contrib.

It’s probably my bad guys. I guess that the SuperImmediateTextField has been designed for short delays.
I’m using it with a 60s delay! (for triggering autosave).