]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/clientpool/SquidPurgeClientPool.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / clientpool / SquidPurgeClientPool.php
1 <?php
2 /**
3  * Squid and Varnish cache purging.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  * http://www.gnu.org/copyleft/gpl.html
19  *
20  * @file
21  */
22 class SquidPurgeClientPool {
23         /** @var array Array of SquidPurgeClient */
24         protected $clients = [];
25
26         /** @var int */
27         protected $timeout = 5;
28
29         /**
30          * @param array $options
31          */
32         function __construct( $options = [] ) {
33                 if ( isset( $options['timeout'] ) ) {
34                         $this->timeout = $options['timeout'];
35                 }
36         }
37
38         /**
39          * @param SquidPurgeClient $client
40          * @return void
41          */
42         public function addClient( $client ) {
43                 $this->clients[] = $client;
44         }
45
46         public function run() {
47                 $done = false;
48                 $startTime = microtime( true );
49                 while ( !$done ) {
50                         $readSockets = $writeSockets = [];
51                         /**
52                          * @var $client SquidPurgeClient
53                          */
54                         foreach ( $this->clients as $clientIndex => $client ) {
55                                 $sockets = $client->getReadSocketsForSelect();
56                                 foreach ( $sockets as $i => $socket ) {
57                                         $readSockets["$clientIndex/$i"] = $socket;
58                                 }
59                                 $sockets = $client->getWriteSocketsForSelect();
60                                 foreach ( $sockets as $i => $socket ) {
61                                         $writeSockets["$clientIndex/$i"] = $socket;
62                                 }
63                         }
64                         if ( !count( $readSockets ) && !count( $writeSockets ) ) {
65                                 break;
66                         }
67                         $exceptSockets = null;
68                         $timeout = min( $startTime + $this->timeout - microtime( true ), 1 );
69                         MediaWiki\suppressWarnings();
70                         $numReady = socket_select( $readSockets, $writeSockets, $exceptSockets, $timeout );
71                         MediaWiki\restoreWarnings();
72                         if ( $numReady === false ) {
73                                 wfDebugLog( 'squid', __METHOD__ . ': Error in stream_select: ' .
74                                         socket_strerror( socket_last_error() ) . "\n" );
75                                 break;
76                         }
77                         // Check for timeout, use 1% tolerance since we aimed at having socket_select()
78                         // exit at precisely the overall timeout
79                         if ( microtime( true ) - $startTime > $this->timeout * 0.99 ) {
80                                 wfDebugLog( 'squid', __CLASS__ . ": timeout ({$this->timeout}s)\n" );
81                                 break;
82                         } elseif ( !$numReady ) {
83                                 continue;
84                         }
85
86                         foreach ( $readSockets as $key => $socket ) {
87                                 list( $clientIndex, ) = explode( '/', $key );
88                                 $client = $this->clients[$clientIndex];
89                                 $client->doReads();
90                         }
91                         foreach ( $writeSockets as $key => $socket ) {
92                                 list( $clientIndex, ) = explode( '/', $key );
93                                 $client = $this->clients[$clientIndex];
94                                 $client->doWrites();
95                         }
96
97                         $done = true;
98                         foreach ( $this->clients as $client ) {
99                                 if ( !$client->isIdle() ) {
100                                         $done = false;
101                                 }
102                         }
103                 }
104                 foreach ( $this->clients as $client ) {
105                         $client->close();
106                 }
107         }
108 }