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
23/**
24 * SquidPurgeClient helper class
25 *
26 * @deprecated Since 1.35 Use MultiHttpClient
27 */
28class SquidPurgeClientPool {
29	/** @var SquidPurgeClient[] */
30	protected $clients = [];
31
32	/** @var int */
33	protected $timeout = 5;
34
35	/**
36	 * @param array $options
37	 */
38	public function __construct( $options = [] ) {
39		if ( isset( $options['timeout'] ) ) {
40			$this->timeout = $options['timeout'];
41		}
42	}
43
44	/**
45	 * @param SquidPurgeClient $client
46	 * @return void
47	 */
48	public function addClient( $client ) {
49		$this->clients[] = $client;
50	}
51
52	public function run() {
53		$done = false;
54		$startTime = microtime( true );
55
56		while ( !$done ) {
57			$readSockets = $writeSockets = [];
58			foreach ( $this->clients as $clientIndex => $client ) {
59				$sockets = $client->getReadSocketsForSelect();
60				foreach ( $sockets as $i => $socket ) {
61					$readSockets["$clientIndex/$i"] = $socket;
62				}
63				$sockets = $client->getWriteSocketsForSelect();
64				foreach ( $sockets as $i => $socket ) {
65					$writeSockets["$clientIndex/$i"] = $socket;
66				}
67			}
68			if ( $readSockets === [] && $writeSockets === [] ) {
69				break;
70			}
71
72			$exceptSockets = null;
73			$timeout = min( $startTime + $this->timeout - microtime( true ), 1 );
74			Wikimedia\suppressWarnings();
75			$numReady = socket_select( $readSockets, $writeSockets, $exceptSockets, $timeout );
76			Wikimedia\restoreWarnings();
77			if ( $numReady === false ) {
78				wfDebugLog( 'squid', __METHOD__ . ': Error in stream_select: ' .
79					socket_strerror( socket_last_error() ) );
80				break;
81			}
82
83			// Check for timeout, use 1% tolerance since we aimed at having socket_select()
84			// exit at precisely the overall timeout
85			if ( microtime( true ) - $startTime > $this->timeout * 0.99 ) {
86				wfDebugLog( 'squid', __CLASS__ . ": timeout ({$this->timeout}s)" );
87				break;
88			} elseif ( !$numReady ) {
89				continue;
90			}
91
92			foreach ( $readSockets as $key => $socket ) {
93				list( $clientIndex, ) = explode( '/', $key );
94				$client = $this->clients[$clientIndex];
95				$client->doReads();
96			}
97			foreach ( $writeSockets as $key => $socket ) {
98				list( $clientIndex, ) = explode( '/', $key );
99				$client = $this->clients[$clientIndex];
100				$client->doWrites();
101			}
102
103			$done = true;
104			foreach ( $this->clients as $client ) {
105				if ( !$client->isIdle() ) {
106					$done = false;
107				}
108			}
109		}
110
111		foreach ( $this->clients as $client ) {
112			$client->close();
113		}
114	}
115}
116