[HACKERS] PostgresNode::poll_query_until hacking

Поиск
Список
Период
Сортировка
От Tom Lane
Тема [HACKERS] PostgresNode::poll_query_until hacking
Дата
Msg-id 12486.1498938782@sss.pgh.pa.us
обсуждение исходный текст
Ответы Re: [HACKERS] PostgresNode::poll_query_until hacking  (Michael Paquier <michael.paquier@gmail.com>)
Список pgsql-hackers
The attached proposed patch changes the TAP test infrastructure's
poll_query_until function in two ways:

1. An optional argument is added to allow specifying the query result
value we're waiting for, overriding the normal "t".  This allows
folding a handwritten delay loop in 007_sync_rep.pl into the
poll_query_until ecosystem.  As far as I've found, there are no other
handwritten delay loops in the TAP tests.

2. poll_query_until is modified to probe 10X per second not once
per second, in keeping with the changes I've been making elsewhere
to remove not-carefully-analyzed 1s delays in the regression tests.

On my workstation, the reduced probe delay shaves a useful amount
of time off the recovery and subscription regression tests.  I also
tried it on dromedary, which is about the slowest hardware I'd care
to run the TAP tests on regularly, and it seems to be about a wash
there --- some tests get faster, but some get slower, presumably due
to more overhead from the probe queries.

I notice that buildfarm member skink (which runs with valgrind)
recently failed a test run due to poll_query_until timing out:

https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=skink&dt=2017-06-30%2000%3A50%3A01

I'm inclined to respond to that either by increasing the fixed
180-second timeout, or by making it configurable from an environment
variable (which Andres would then have to add to skink's configuration).

Thoughts?

            regards, tom lane

diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm
index f4fa600..4346423 100644
*** a/src/test/perl/PostgresNode.pm
--- b/src/test/perl/PostgresNode.pm
*************** sub psql
*** 1213,1248 ****

  =pod

! =item $node->poll_query_until(dbname, query)

! Run a query once a second, until it returns 't' (i.e. SQL boolean true).
! Continues polling if psql returns an error result. Times out after 180 seconds.

  =cut

  sub poll_query_until
  {
!     my ($self, $dbname, $query) = @_;

!     my $max_attempts = 180;
!     my $attempts     = 0;
      my ($stdout, $stderr);

      while ($attempts < $max_attempts)
      {
-         my $cmd =
-           [ 'psql', '-XAt', '-c', $query, '-d', $self->connstr($dbname) ];
          my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr;

          chomp($stdout);
          $stdout =~ s/\r//g if $TestLib::windows_os;
!         if ($stdout eq "t")
          {
              return 1;
          }

!         # Wait a second before retrying.
!         sleep 1;
          $attempts++;
      }

--- 1213,1255 ----

  =pod

! =item $node->poll_query_until($dbname, $query [, $expected ])

! Run B<$query> repeatedly, until it returns the B<$expected> result
! ('t', or SQL boolean true, by default).
! Continues polling if B<psql> returns an error result.
! Times out after 180 seconds.
! Returns 1 if successful, 0 if timed out.

  =cut

  sub poll_query_until
  {
!     my ($self, $dbname, $query, $expected) = @_;

!     $expected = 't' unless defined($expected);    # default value
!
!     my $cmd =
!         [ 'psql', '-XAt', '-c', $query, '-d', $self->connstr($dbname) ];
      my ($stdout, $stderr);
+     my $max_attempts = 180 * 10;
+     my $attempts     = 0;

      while ($attempts < $max_attempts)
      {
          my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr;

          chomp($stdout);
          $stdout =~ s/\r//g if $TestLib::windows_os;
!
!         if ($stdout eq $expected)
          {
              return 1;
          }

!         # Wait 0.1 second before retrying.
!         select undef, undef, undef, 0.1;
!
          $attempts++;
      }

diff --git a/src/test/recovery/t/007_sync_rep.pl b/src/test/recovery/t/007_sync_rep.pl
index 8e3cc5e..0f999f0 100644
*** a/src/test/recovery/t/007_sync_rep.pl
--- b/src/test/recovery/t/007_sync_rep.pl
*************** use Test::More tests => 11;
*** 9,15 ****
  my $check_sql =
  "SELECT application_name, sync_priority, sync_state FROM pg_stat_replication ORDER BY application_name;";

! # Check that sync_state of each standby is expected.
  # If $setting is given, synchronous_standby_names is set to it and
  # the configuration file is reloaded before the test.
  sub test_sync_state
--- 9,15 ----
  my $check_sql =
  "SELECT application_name, sync_priority, sync_state FROM pg_stat_replication ORDER BY application_name;";

! # Check that sync_state of each standby is expected (waiting till it is).
  # If $setting is given, synchronous_standby_names is set to it and
  # the configuration file is reloaded before the test.
  sub test_sync_state
*************** sub test_sync_state
*** 23,46 ****
          $self->reload;
      }

!     my $timeout_max = 30;
!     my $timeout     = 0;
!     my $result;
!
!     # A reload may take some time to take effect on busy machines,
!     # hence use a loop with a timeout to give some room for the test
!     # to pass.
!     while ($timeout < $timeout_max)
!     {
!         $result = $self->safe_psql('postgres', $check_sql);
!
!         last if ($result eq $expected);
!
!         $timeout++;
!         sleep 1;
!     }
!
!     is($result, $expected, $msg);
  }

  # Initialize master node
--- 23,29 ----
          $self->reload;
      }

!     ok( $self->poll_query_until('postgres', $check_sql, $expected), $msg);
  }

  # Initialize master node

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Fabien COELHO
Дата:
Сообщение: Re: [HACKERS] WIP Patch: Pgbench Serialization and deadlock errors
Следующее
От: Ricky Stevens
Дата:
Сообщение: [HACKERS] Using postgres planner as standalone component