I was thinking, but maybe it would be nice to use some kind of semaphore for this construction. So I found an implementation on the net of a Dijkstra semaphore. This semaphore controls the access to a pool of resources. The code looks very solid to me. All you have to do is to call aquire() before the connection is retrieved from the pool and release() when it is put back. (When the pool grows is also needs a release()).
Since this was some example code I think no one will care if we put it in a
MMBase package.
This will make the code somewhat cleaner I think.
gr,
Gerard
----- Original Message -----
From: "Marcel Maatkamp" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, August 29, 2002 8:46 PM
Subject: MultiConnection and lost connections
> 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.j
ava:46)
> at org.mmbase.module.database.JDBC.getConnection(JDBC.java:274)
> at
org.mmbase.module.database.support.MMSQL92Node.getConnection(MMSQL92Node.jav
a: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:109
0)
> 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
>
>
>
DjikstraSemaphore.java
Description: Binary data
