We are having serious performance problems (delays of various seconds) due to
the lookup process in Component:initModel() that tries to find a wrapModel
looking for an parent with an IInheritableModel.

The problem is the following: if a component has no model defined,
initModel() looks for a parent that has an IInheritableModel. Since it has
to consult the model of that parent, it calls getModel(). If the parent
itself has no model (it's just a container that has a layout function),
within getModel() there is a new call to initModel(), this time to look for
a model for that parent.

This is a simple simulation of what happens in Component: If I have a
component graph, in which a component is contained in 4 containers of which
3 have no model, I end up calling 8 times the initModel() method of the
topmost container without model.

public class Component {
        private String id;
        private Component parent = null;
        private Object model = null;
        private int initCount = 0;
        
        public Component(Component parent,String id,Object model) {
                this.parent = parent;
                this.id = id;
                this.model = model;
                
                if (model == null)
                        initModel();
        }
        
        public Object getModel() {
                if (model == null)
                        initModel();
                return(model);
        }
        
        public void initModel() {
                initCount++;
                for (Component parent = this.parent; parent != null; parent =
parent.parent) {
                        parent.getModel();
                }       
        }
        
        @Override
        public String toString() {
                return("id: "+id+" initCount: "+initCount);
        }

        public static void main(String[] args) {
                Component a = new Component(null,"a","a");
                Component b = new Component(a,"b",null);
                Component c = new Component(b,"c",null);
                Component d = new Component(c,"d",null);
                Component e = new Component(d,"e",null);

                System.out.println(b);
                System.out.println(c);
                System.out.println(d);
                System.out.println(e);
        }
}

In a real usecase, the component graph ends up being a lot larger than this
simple example, and the effect of calling initModel() can end up causing a
response delay of 10's of seconds.

We can solve the problem by overwriting the initModel() method in containers
that shouldn't have a model, or give them a mock model.

But I think there is a conceptual error in the component implementation: I
think initModel() should not be called from the method getModel(). Once
decided that there is no model for a component, it should not try and get
one each time we want to get it. I.e., initModel should be called only once
for each component. Am I right ?

Jan.

-- 
View this message in context: 
http://www.nabble.com/Performance-problems-due-to-Component%3AinitModel%28%29-tf3362476.html#a9354170
Sent from the Wicket - Dev mailing list archive at Nabble.com.

Reply via email to