You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Tobia Conforto <to...@linux.it> on 2008/06/17 11:47:32 UTC

Database input-module and question about deadlocks

Hello

I'm having all sorts of problems with an input module I wrote that  
makes a few databases queries to perform its work, using JDBI.  I'm  
still using Cocoon 2.1.  I don't understand Avalon much and I'd  
appreciate it if some of you could look over my code and tell me if  
you see something blatantly wrong.

Moreover, I have a more basic question about database connections in  
Cocoon.  Every call to my pipeline passes through a couple of  
SQLTransformers, then a LinkRewriter transformer that calls my input  
module many times to expand some particular links, whenever such links  
appear in the SAX stream.  Every SQLTransformer and every call to my  
input module needs a DB connection object to perform its work, ie. the  
objects returned by  
dataSourceSelector.select("datasource").getConnection().

How can I avoid deadlock situations?

I picture many requests arriving all at the same time, all the  
components at the beginning of the pipelines getting their  
connections, emptying the connection pool, and then all the pipelines  
going into deadlock at a later stage because my input module (or any  
other component called at a later stage) cannot get its connection.  I  
have the feeling this is exactly what's happening in some of my  
tests.  What would be the correct approach here?


Tobia


Here is the skeleton of my input module:

--------------------------------------------------------------------------------------------------------
public class MyInputModule extends AbstractInputModule implements  
Serviceable, Disposable, ThreadSafe {

   protected ServiceManager manager;
   protected ServiceSelector dataSourceSelector;

   public void service(ServiceManager manager) throws ServiceException {
     this.manager = manager;
     dataSourceSelector = (ServiceSelector)  
manager.lookup(DataSourceComponent.ROLE + "Selector");
   }

   public void dispose() {
     manager.release(dataSourceSelector);
   }

   private class DataSourceWrapper implements  
org.skife.jdbi.ConnectionFactory {

     private DataSourceComponent ds;

     public DataSourceWrapper(DataSourceComponent ds) {
       this.ds = ds;
     }

     public Connection getConnection() throws SQLException {
       return ds.getConnection();
     }
   }

   public Object getAttribute(String url, Configuration conf, Map om)  
throws ConfigurationException {

     DataSourceComponent datasource = null;
     org.skife.jdbi.Handle dbi = null;
     try {

       try {
         datasource = (DataSourceComponent)  
dataSourceSelector.select("some-fixed-datasource-name");
       } catch (ServiceException e) {
         getLogger().warn("Error getting datasource", e);
       }
       dbi = new org.skife.jdbi.DBI(new  
DataSourceWrapper(datasource)).open();

       /*
        * here goes lots of code using the dbi object to make queries,  
etc.
        */

     } finally {

       try {
         if (dbi != null) dbi.close();
       } catch (org.skife.jdbi.DBIError dbe) {
         getLogger().warn("Error closing JDBI handle", dbe);
       }
       if (datasource != null) dataSourceSelector.release(datasource);

     }
   }
}
--------------------------------------------------------------------------------------------------------