[DBD::Pg] Revert kill version of ping testing: use better file descriptor method as proposed by Tim Bunce. Change some of the ping logic in dbdimp.c Still fails on a disconnect while in failed transaction. Not sure if there is a clean way to detect that yet...
[email protected] Sun, 28 Dec 2014 01:03:53 +0000
| Newsgroups | perl.dbd.pg.changes |
|---|---|
| Message-ID | <[email protected]> |
Committed by Greg Sabino Mullane <[email protected]> Revert kill version of ping testing: use better file descriptor method as proposed by Tim Bunce. Change some of the ping logic in dbdimp.c Still fails on a disconnect while in failed transaction. Not sure if there is a clean way to detect that yet... --- dbdimp.c | 9 ++++++--- t/03dbmethod.t | 30 +++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/dbdimp.c b/dbdimp.c index 334b19e..359865c 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -476,18 +476,21 @@ int dbd_db_ping (SV * dbh) /* No matter what state we are in, send a SELECT to the backend */ status = _result(aTHX_ imp_dbh, "SELECT 'DBD::Pg ping test'"); + /* If we are idle or in a transaction, we should see tuples */ if (0 == tstatus || 2 == tstatus) { - /* If we are simply idle or in a transaction, we should see tuples */ - if (PGRES_TUPLES_OK == status) { if (TEND_slow) TRC(DBILOGFP, "%sEnd dbd_pg_ping (result: 1 PGRES_TUPLES_OK)\n", THEADER_slow); return 1+tstatus; } + /* Something is wrong, so we return an error */ + return -2; } - /* A status of 7 could indicate a failed query or a dead database. We need PQstatus to be sure */ + /* We are in some other state. As a status of 7 could be a bad query or a dead database, + we need to call PQstatus to be sure + */ if (CONNECTION_BAD == PQstatus(imp_dbh->conn)) { if (TEND_slow) TRC(DBILOGFP, "%sEnd dbd_pg_ping (PQstatus returned CONNECTION_BAD)\n", THEADER_slow); return -3; diff --git a/t/03dbmethod.t b/t/03dbmethod.t index 77ba407..e78f75d 100644 --- a/t/03dbmethod.t +++ b/t/03dbmethod.t @@ -1925,17 +1925,37 @@ $t='DB handle method "ping" returns 1 on an idle connection'; $dbh->commit(); is ($dbh->ping(), 1, $t); -$t='DB handle method "ping" returns 0 when the underlying connection is gone'; +$t='DB handle method "ping" returns 0 after a lost network connection (outside transaction)'; +my $fd = $dbh->{pg_socket} or die "Could not determine socket"; +open(DBH_PG_FH, "<&=".$fd) or die "Could not open socket: $!"; +close DBH_PG_FH or die "Could not close socket: $!"; +is ($dbh->ping(), 0, $t); -$pid = $dbh->selectall_arrayref('SELECT pg_backend_pid()')->[0][0]; -$dbh->commit(); -kill 15, $pid; -sleep 1; +## Reconnect, and try the same thing but inside a transaction +$t='DB handle method "ping" returns 0 after a lost network connection (inside transaction)'; +diag "About to call..."; +$dbh->disconnect(); +$dbh = connect_database({nosetup => 1}); +$dbh->do("SELECT 'DBD::Pg testing'"); +$fd = $dbh->{pg_socket} or die "Could not determine socket"; +open(DBH_PG_FH, "<&=".$fd) or die "Could not open socket: $!"; +close DBH_PG_FH or die "Could not close socket: $!"; +is ($dbh->ping(), 0, $t); + +$t='DB handle method "ping" returns 0 after a lost network connection (inside failed transaction)'; +$dbh->{InactiveDestroy} = 1; +undef $dbh; +$dbh = connect_database({nosetup => 1}); +eval { $dbh->do("SELECT 'DBD::Pg testing, will fail'::int"); }; +$fd = $dbh->{pg_socket} or die "Could not determine socket"; +open(DBH_PG_FH, "<&=".$fd) or die "Could not open socket: $!"; +close DBH_PG_FH or die "Could not close socket: $!"; is ($dbh->ping(), 0, $t); $dbh->disconnect(); $dbh = connect_database({nosetup => 1}); + # # Test of the "pg_ping" database handle method # -- 1.8.4