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);
}
}
}
--------------------------------------------------------------------------------------------------------