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.