rdbms: make LoadBalancer::waitForAll() better respect the timeout
authorAaron Schulz <aschulz@wikimedia.org>
Tue, 16 Jan 2018 16:58:59 +0000 (17:58 +0100)
committerAaron Schulz <aschulz@wikimedia.org>
Sun, 21 Jan 2018 05:31:15 +0000 (05:31 +0000)
If several replicas (or even all) had replication stuck, then the
timeout would happen for each server, one after another.

Change-Id: Id5431360b9cde7e5dc0115a1f41b9903003f47c4

includes/libs/rdbms/loadbalancer/LoadBalancer.php

index e80b952..9c5a107 100644 (file)
@@ -518,6 +518,8 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function waitForAll( $pos, $timeout = null ) {
+               $timeout = $timeout ?: $this->mWaitTimeout;
+
                $oldPos = $this->mWaitForPos;
                try {
                        $this->mWaitForPos = $pos;
@@ -526,7 +528,12 @@ class LoadBalancer implements ILoadBalancer {
                        $ok = true;
                        for ( $i = 1; $i < $serverCount; $i++ ) {
                                if ( $this->mLoads[$i] > 0 ) {
-                                       $ok = $this->doWait( $i, true, $timeout ) && $ok;
+                                       $start = microtime( true );
+                                       $ok = $this->doWait( $i, true, max( 1, (int)$timeout ) ) && $ok;
+                                       $timeout -= ( microtime( true ) - $start );
+                                       if ( $timeout <= 0 ) {
+                                               break; // timeout reached
+                                       }
                                }
                        }
                } finally {