1<?php
2
3declare(strict_types = 1);
4
5namespace Elasticsearch\ConnectionPool;
6
7use Elasticsearch\Common\Exceptions\NoNodesAvailableException;
8use Elasticsearch\ConnectionPool\Selectors\SelectorInterface;
9use Elasticsearch\Connections\Connection;
10use Elasticsearch\Connections\ConnectionInterface;
11use Elasticsearch\Connections\ConnectionFactoryInterface;
12
13class StaticNoPingConnectionPool extends AbstractConnectionPool implements ConnectionPoolInterface
14{
15    /**
16     * @var int
17     */
18    private $pingTimeout    = 60;
19
20    /**
21     * @var int
22     */
23    private $maxPingTimeout = 3600;
24
25    /**
26     * {@inheritdoc}
27     */
28    public function __construct($connections, SelectorInterface $selector, ConnectionFactoryInterface $factory, $connectionPoolParams)
29    {
30        parent::__construct($connections, $selector, $factory, $connectionPoolParams);
31    }
32
33    public function nextConnection(bool $force = false): ConnectionInterface
34    {
35        $total = count($this->connections);
36        while ($total--) {
37            /**
38 * @var Connection $connection
39*/
40            $connection = $this->selector->select($this->connections);
41            if ($connection->isAlive() === true) {
42                return $connection;
43            }
44
45            if ($this->readyToRevive($connection) === true) {
46                return $connection;
47            }
48        }
49
50        throw new NoNodesAvailableException("No alive nodes found in your cluster");
51    }
52
53    public function scheduleCheck(): void
54    {
55    }
56
57    private function readyToRevive(Connection $connection): bool
58    {
59        $timeout = min(
60            $this->pingTimeout * pow(2, $connection->getPingFailures()),
61            $this->maxPingTimeout
62        );
63
64        if ($connection->getLastPing() + $timeout < time()) {
65            return true;
66        } else {
67            return false;
68        }
69    }
70}
71