Fix postgresql connection leaks
Return connection to pool on connection error (see #1708) Fix leaks on persist_connection=false (#1711) Includes testcase for #1711
This commit is contained in:
parent
c81f28fc41
commit
0c5d5ca99c
3 changed files with 35 additions and 14 deletions
|
@ -143,7 +143,7 @@ public:
|
|||
|
||||
bool isOK() const
|
||||
{
|
||||
return (PQstatus(conn_) != CONNECTION_BAD);
|
||||
return (!closed_) && (PQstatus(conn_) != CONNECTION_BAD);
|
||||
}
|
||||
|
||||
void close()
|
||||
|
|
|
@ -113,10 +113,12 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
|||
if (pool)
|
||||
{
|
||||
shared_ptr<Connection> conn = pool->borrowObject();
|
||||
if (conn && conn->isOK())
|
||||
{
|
||||
if (!conn) return;
|
||||
|
||||
PoolGuard<shared_ptr<Connection>,
|
||||
shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
||||
if (conn->isOK())
|
||||
{
|
||||
|
||||
desc_.set_encoding(conn->client_encoding());
|
||||
|
||||
|
@ -429,6 +431,7 @@ postgis_datasource::~postgis_datasource()
|
|||
if (conn)
|
||||
{
|
||||
conn->close();
|
||||
pool->returnObject(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -693,6 +696,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
|||
if (conn)
|
||||
{
|
||||
err_msg += conn->status();
|
||||
pool->returnObject(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -714,10 +718,11 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t
|
|||
if (pool)
|
||||
{
|
||||
shared_ptr<Connection> conn = pool->borrowObject();
|
||||
if (conn && conn->isOK())
|
||||
{
|
||||
if (!conn) return featureset_ptr();
|
||||
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
||||
|
||||
if (conn->isOK())
|
||||
{
|
||||
if (geometryColumn_.empty())
|
||||
{
|
||||
std::ostringstream s_error;
|
||||
|
@ -798,10 +803,10 @@ box2d<double> postgis_datasource::envelope() const
|
|||
if (pool)
|
||||
{
|
||||
shared_ptr<Connection> conn = pool->borrowObject();
|
||||
if (conn && conn->isOK())
|
||||
{
|
||||
if (!conn) return extent_;
|
||||
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
||||
|
||||
if (conn->isOK())
|
||||
{
|
||||
std::ostringstream s;
|
||||
|
||||
if (geometryColumn_.empty())
|
||||
|
@ -890,10 +895,10 @@ boost::optional<mapnik::datasource::geometry_t> postgis_datasource::get_geometry
|
|||
if (pool)
|
||||
{
|
||||
shared_ptr<Connection> conn = pool->borrowObject();
|
||||
if (conn && conn->isOK())
|
||||
{
|
||||
if (!conn) return result;
|
||||
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
||||
|
||||
if (conn->isOK())
|
||||
{
|
||||
std::ostringstream s;
|
||||
std::string g_type;
|
||||
try
|
||||
|
|
|
@ -495,6 +495,22 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
|
|||
eq_(feat['gid'],2)
|
||||
eq_(feat['int_field'],922337203685477580)
|
||||
|
||||
def test_persist_connection_off():
|
||||
# NOTE: max_size should be equal or greater than
|
||||
# the pool size. There's currently no API to
|
||||
# check nor set that size, but the current
|
||||
# default is 20, so we use that value. See
|
||||
# http://github.com/mapnik/mapnik/issues/863
|
||||
max_size = 20
|
||||
for i in range(0, max_size+1):
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,
|
||||
max_size=1, # unused
|
||||
persist_connection=False,
|
||||
table='(select ST_MakePoint(0,0) as g, pg_backend_pid() as p, 1 as v) as w',
|
||||
geometry_field='g')
|
||||
fs = ds.featureset()
|
||||
eq_(fs.next()['v'], 1)
|
||||
|
||||
atexit.register(postgis_takedown)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Reference in a new issue