PHP7 Pool

This commit is contained in:
Dominik Liebler 2016-09-22 14:16:12 +02:00
parent 7beb1420b4
commit 61a6f03f04
5 changed files with 58 additions and 98 deletions

View File

@ -1,51 +0,0 @@
<?php
namespace DesignPatterns\Creational\Pool;
class Processor
{
private $pool;
private $processing = 0;
private $maxProcesses = 3;
private $waitingQueue = array();
public function __construct(Pool $pool)
{
$this->pool = $pool;
}
public function process($image)
{
if ($this->processing++ < $this->maxProcesses) {
$this->createWorker($image);
} else {
$this->pushToWaitingQueue($image);
}
}
private function createWorker($image)
{
$worker = $this->pool->get();
$worker->run($image, array($this, 'processDone'));
}
public function processDone($worker)
{
$this->processing--;
$this->pool->dispose($worker);
if (count($this->waitingQueue) > 0) {
$this->createWorker($this->popFromWaitingQueue());
}
}
private function pushToWaitingQueue($image)
{
$this->waitingQueue[] = $image;
}
private function popFromWaitingQueue()
{
return array_pop($this->waitingQueue);
}
}

View File

@ -33,21 +33,15 @@ Code
You can also find these code on `GitHub`_
Pool.php
WorkerPool.php
.. literalinclude:: Pool.php
.. literalinclude:: WorkerPool.php
:language: php
:linenos:
Processor.php
StringReverseWorker.php
.. literalinclude:: Processor.php
:language: php
:linenos:
Worker.php
.. literalinclude:: Worker.php
.. literalinclude:: StringReverseWorker.php
:language: php
:linenos:
@ -60,11 +54,5 @@ Tests/PoolTest.php
:language: php
:linenos:
Tests/TestWorker.php
.. literalinclude:: Tests/TestWorker.php
:language: php
:linenos:
.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Pool
.. __: http://en.wikipedia.org/wiki/Object_pool_pattern

View File

@ -2,18 +2,20 @@
namespace DesignPatterns\Creational\Pool;
class Worker
class StringReverseWorker
{
/**
* @var \DateTime
*/
private $createdAt;
public function __construct()
{
// let's say that constuctor does really expensive work...
// for example creates "thread"
$this->createdAt = new \DateTime();
}
public function run($image, array $callback)
public function run(string $text)
{
// do something with $image...
// and when it's done, execute callback
call_user_func($callback, $this);
return strrev($text);
}
}

View File

@ -2,21 +2,28 @@
namespace DesignPatterns\Creational\Pool\Tests;
use DesignPatterns\Creational\Pool\Pool;
use DesignPatterns\Creational\Pool\WorkerPool;
class PoolTest extends \PHPUnit_Framework_TestCase
{
public function testPool()
public function testCanGetNewInstancesWithGet()
{
$pool = new Pool('DesignPatterns\Creational\Pool\Tests\TestWorker');
$worker = $pool->get();
$pool = new WorkerPool();
$worker1 = $pool->get();
$worker2 = $pool->get();
$this->assertEquals(1, $worker->id);
$this->assertCount(2, $pool);
$this->assertNotSame($worker1, $worker2);
}
$worker->id = 5;
$pool->dispose($worker);
public function testCanGetSameInstanceTwiceWhenDisposingItFirst()
{
$pool = new WorkerPool();
$worker1 = $pool->get();
$pool->dispose($worker1);
$worker2 = $pool->get();
$this->assertEquals(5, $pool->get()->id);
$this->assertEquals(1, $pool->get()->id);
$this->assertCount(1, $pool);
$this->assertSame($worker1, $worker2);
}
}

View File

@ -2,29 +2,43 @@
namespace DesignPatterns\Creational\Pool;
class Pool
class WorkerPool implements \Countable
{
private $instances = [];
/**
* @var StringReverseWorker[]
*/
private $occupiedWorkers = [];
/**
* @var StringReverseWorker[]
*/
private $freeWorkers = [];
private $class;
public function __construct($class)
public function get(): StringReverseWorker
{
$this->class = $class;
}
public function get()
{
if (count($this->instances) > 0) {
return array_pop($this->instances);
if (count($this->freeWorkers) == 0) {
$worker = new StringReverseWorker();
} else {
$worker = array_pop($this->freeWorkers);
}
return new $this->class();
$this->occupiedWorkers[spl_object_hash($worker)] = $worker;
return $worker;
}
public function dispose($instance)
public function dispose(StringReverseWorker $worker)
{
$this->instances[] = $instance;
$key = spl_object_hash($worker);
if (isset($this->occupiedWorkers[$key])) {
unset($this->occupiedWorkers[$key]);
$this->freeWorkers[$key] = $worker;
}
}
public function count(): int
{
return count($this->occupiedWorkers) + count($this->freeWorkers);
}
}