From: Peter Rabbitson Date: Thu, 8 Jan 2015 00:42:52 +0000 (+0100) Subject: Fix Postgres test hang with DBD::Pg 3.5.0+ (work around RT#100648) X-Git-Tag: v0.08271~16 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b409dead875c0ea3984c66ff5f742628d0dd71b4;p=dbsrgits%2FDBIx-Class.git Fix Postgres test hang with DBD::Pg 3.5.0+ (work around RT#100648) ( cherry-pick of 731c2d8b ) It is not 100% clear to me why this is happening, as the change discussed[1] was not supposed to change behaviour outside of a transaction. The test in question essentially does a blocking request with a timeout. The way the default DBIC machinery works is to issue a ping() after the timeout induced exception, in order to opossibly retry the operation IFF the link went stale ($dbh thinks everything is in order, the RDBMS believes otherwise). After the changes in 3.5.0 this ping() now hangs, even though the access pattern did not change (there are no transactions involved on the handle in question). Either way, the fix is simple: just shim-away the ping for the duration of the test. In general this should be resolved on a higher level by disabling retries for the duration of the test (or maybe even disabling retries by default in the distant feature - see RT#47005) [1] https://rt.cpan.org/Ticket/Display.html?id=100648#txn-1438093 --- diff --git a/Changes b/Changes index d557c39..777b774 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,10 @@ Revision history for DBIx::Class + * Fixes + - Fix hang in t/72pg.t when run against DBD::Pg 3.5.0. The ping() + implementation changes due to RT#100648 made an alarm() based + timeout lock-prone. + 0.08270 2014-01-30 21:54 (PST) * Fixes - Fix 0.08260 regression in DBD::SQLite bound int handling. Inserted diff --git a/lib/DBIx/Class/Optional/Dependencies.pm b/lib/DBIx/Class/Optional/Dependencies.pm index 23ffebe..79b56a0 100644 --- a/lib/DBIx/Class/Optional/Dependencies.pm +++ b/lib/DBIx/Class/Optional/Dependencies.pm @@ -454,7 +454,6 @@ my $reqs = { ? ( # when changing this list make sure to adjust xt/optional_deps.t %$rdbms_pg, - ($^O ne 'MSWin32' ? ('Sys::SigAction' => '0') : ()), 'DBD::Pg' => '2.009002', ) : () }, diff --git a/t/72pg.t b/t/72pg.t index 44b723c..6371775 100644 --- a/t/72pg.t +++ b/t/72pg.t @@ -337,13 +337,6 @@ lives_ok { $cds->update({ year => '2010' }) } 'Update on prefetched rs'; ## Test SELECT ... FOR UPDATE SKIP: { - if(eval { require Sys::SigAction }) { - Sys::SigAction->import( 'set_sig_handler' ); - } - else { - skip "Sys::SigAction is not available", 6; - } - my ($timed_out, $artist2); for my $t ( @@ -382,10 +375,23 @@ lives_ok { $cds->update({ year => '2010' }) } 'Update on prefetched rs'; $timed_out = 0; eval { - my $h = set_sig_handler( 'ALRM', sub { die "DBICTestTimeout" } ); - alarm(2); + # can not use %SIG assignment directly - we need sigaction below + # localization to a block still works however + local $SIG{ALRM}; + + POSIX::sigaction( POSIX::SIGALRM() => POSIX::SigAction->new( + sub { die "DBICTestTimeout" }, + )); + $artist2 = $schema2->resultset('Artist')->find(1); $artist2->name('fooey'); + + # FIXME - this needs to go away in lieu of a non-retrying runner + # ( i.e. after solving RT#47005 ) + local *DBIx::Class::Storage::DBI::_ping = sub { 1 }, DBIx::Class::_ENV_::OLD_MRO && Class::C3->reinitialize() + if DBIx::Class::_Util::modver_gt_or_eq( 'DBD::Pg' => '3.5.0' ); + + alarm(1); $artist2->update; alarm(0); }; diff --git a/xt/optional_deps.t b/xt/optional_deps.t index 0ae8023..781273c 100644 --- a/xt/optional_deps.t +++ b/xt/optional_deps.t @@ -119,7 +119,6 @@ is_deeply( is_deeply( DBIx::Class::Optional::Dependencies->req_list_for('test_rdbms_pg'), { - $^O ne 'MSWin32' ? ('Sys::SigAction' => '0') : (), 'DBD::Pg' => '2.009002', }, 'optional dependencies for testing Postgres with ENV var ok');