Hi,
(The following happens on a machine which does my new code for the
getRelated, which does a basicSearch, which does frequenty a getConnection()
Since it is a very heavily used machine userwise, and page-caching is turned off for
some
reason or another, it pounds the dabatase with queries in a huge tempo)
I've moved some import stuff to a faster machine because I will run imports in the
middle
of the night, after the load of users is somewhat reduced. After I ran some
testimports on huge
load, I frequenty stumbled across this exception (all is cvs up2date):
16:15 ERROR org.mmbase.module.core.MMBase.getConnection(640):
java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:427)
at org.mmbase.module.database.MultiPool.getFree(MultiPool.java:178)
at
org.mmbase.module.database.MultiPoolHandler.getConnection(MultiPoolHandler.java:46)
at org.mmbase.module.database.JDBC.getConnection(JDBC.java:274)
at
org.mmbase.module.database.support.MMSQL92Node.getConnection(MMSQL92Node.java:1470)
at org.mmbase.module.core.MMBase.getConnection(MMBase.java:632)
at
org.mmbase.module.core.MMObjectBuilder.basicSearch(MMObjectBuilder.java:1117)
at
org.mmbase.module.core.MMObjectBuilder.searchVector(MMObjectBuilder.java:1090)
at org.mmbase.module.core.MMObjectBuilder.search(MMObjectBuilder.java:1071)
at org.mmbase.module.builders.Vwmtasks.getVwmTasks(Vwmtasks.java:214)
at org.mmbase.module.builders.Vwmtasks.run(Vwmtasks.java:129)
at java.lang.Thread.run(Thread.java:536)
The code which is responsable for this exception is the following:
org.mmbase.module.database.MultiPool.getFree(MultiPool.java:178):
public MultiConnection getFree() {
while (pool.size()==0) {
try{
Thread.sleep(10000);
} catch(InterruptedException e){
log.warn("getFree sleep INT");
}
}
synchronized(synobj) {
con=(MultiConnection)pool.elementAt(0);
con.claim();
pool.removeElementAt(0);
busypool.addElement(con);
}
I suspect the following:
- thread A (maybe sleeps and) sees pool.size() > 0
- thread B interrupts and fetches the last connection
- thread A now enters the synchronized and does a pool.elementAt(0),
which horribly fails, because there aren't any left
I have moved the synchronized over the while-loop. This will have the
consecuence of everyone wanting a connection to block when there
aren't any left, so a Thread.sleep(5000) is in my eyes more acceptable,
even when it still is a bit high.
The method now looks like this:
public MultiConnection getFree() {
MultiConnection con=null;
totalConnections++;
synchronized(synobj) {
while (pool.size()==0) {
try{
Thread.sleep(10000);
} catch(InterruptedException e){
log.warn("getFree sleep INT");
}
if (log.isDebugEnabled()) {
log.debug("sleep on "+this);
}
} // end while
con=(MultiConnection)pool.elementAt(0);
con.claim();
pool.removeElementAt(0);
busypool.addElement(con);
} // end synchronized
return(con);
}
My observation sofar is:
After having it installed on the machine I now see that connections are blocked after
say 10 min. This is due to the fact that the nodecache is empty and thus every (new)
node
has to be fetched from the database which is done in a huge tempo. I have made
some adjustments so I can see if connections are being returned. Since it is
quite late I will finish this tomorrow.. The machine will do some heavy importing
tonight so I am quite eager to see how it handles this.
gr,
marcel