ConnectionPool::freeConnection()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
ccs 0
cts 9
cp 0
rs 9.6666
cc 2
eloc 6
nc 2
nop 1
crap 6
1
<?php
2
3
namespace Thruster\Component\MysqlClient;
4
5
use mysqli;
6
use SplObjectStorage;
7
use Thruster\Component\MysqlClient\Exception\ConnectionException;
8
use Thruster\Component\Promise\Deferred;
9
use Thruster\Component\Promise\ExtendedPromiseInterface;
10
use Thruster\Component\Promise\FulfilledPromise;
11
use Thruster\Component\Promise\RejectedPromise;
12
13
/**
14
 * Class ConnectionPool
15
 *
16
 * @package Thruster\Component\MysqlClient
17
 * @author  Aurimas Niekis <[email protected]>
18
 */
19
class ConnectionPool
20
{
21
    /**
22
     * @var callable
23
     */
24
    private $connectionFactory;
25
26
    /**
27
     * @var SplObjectStorage
28
     */
29
    private $connectionPool;
30
31
    /**
32
     * @var SplObjectStorage
33
     */
34
    private $idleConnections;
35
36
    /**
37
     * @var Deferred[]
38
     */
39
    private $waiting;
40
41
    /**
42
     * @var int
43
     */
44
    private $maxOpenConnections;
45
46
    public function __construct(callable $connectionFactory, int $maxOpenConnections = 100)
47
    {
48
        $this->connectionPool  = new SplObjectStorage();
49
        $this->idleConnections = new SplObjectStorage();
50
51
        $this->waiting            = [];
52
        $this->maxOpenConnections = $maxOpenConnections;
53
        $this->connectionFactory  = $connectionFactory;
54
    }
55
56
    public function getConnection() : ExtendedPromiseInterface
57
    {
58
        if ($this->idleConnections->count() > 0) {
59
            $this->idleConnections->rewind();
60
61
            $connection = $this->idleConnections->current();
62
            $this->idleConnections->detach($connection);
63
64
            return new FulfilledPromise($connection);
65
        }
66
67
        if ($this->connectionPool->count() >= $this->maxOpenConnections) {
68
            $deferred = new Deferred();
69
70
            $this->waiting[] = $deferred;
71
72
            return $deferred->promise();
73
        }
74
75
        $connection = call_user_func($this->connectionFactory);
76
77
        if (false !== $connection) {
78
            $this->connectionPool->attach($connection);
79
80
            return new FulfilledPromise($connection);
81
        } else {
82
            return new RejectedPromise(new ConnectionException());
83
        }
84
    }
85
86
    public function freeConnection(mysqli $connection)
87
    {
88
        if (count($this->waiting) > 0) {
89
            $deferred = array_shift($this->waiting);
90
            $deferred->resolve($connection);
91
        } else {
92
            $this->idleConnections->attach($connection);
93
        }
94
    }
95
}
96