mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-02-22 16:54:13 +01:00
PHP7 Pool
This commit is contained in:
parent
7beb1420b4
commit
61a6f03f04
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -33,21 +33,15 @@ Code
|
|||||||
|
|
||||||
You can also find these code on `GitHub`_
|
You can also find these code on `GitHub`_
|
||||||
|
|
||||||
Pool.php
|
WorkerPool.php
|
||||||
|
|
||||||
.. literalinclude:: Pool.php
|
.. literalinclude:: WorkerPool.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
Processor.php
|
StringReverseWorker.php
|
||||||
|
|
||||||
.. literalinclude:: Processor.php
|
.. literalinclude:: StringReverseWorker.php
|
||||||
:language: php
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
Worker.php
|
|
||||||
|
|
||||||
.. literalinclude:: Worker.php
|
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
@ -60,11 +54,5 @@ Tests/PoolTest.php
|
|||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
Tests/TestWorker.php
|
|
||||||
|
|
||||||
.. literalinclude:: Tests/TestWorker.php
|
|
||||||
:language: php
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Pool
|
.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Pool
|
||||||
.. __: http://en.wikipedia.org/wiki/Object_pool_pattern
|
.. __: http://en.wikipedia.org/wiki/Object_pool_pattern
|
||||||
|
@ -2,18 +2,20 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\Pool;
|
namespace DesignPatterns\Creational\Pool;
|
||||||
|
|
||||||
class Worker
|
class StringReverseWorker
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \DateTime
|
||||||
|
*/
|
||||||
|
private $createdAt;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
// let's say that constuctor does really expensive work...
|
$this->createdAt = new \DateTime();
|
||||||
// for example creates "thread"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run($image, array $callback)
|
public function run(string $text)
|
||||||
{
|
{
|
||||||
// do something with $image...
|
return strrev($text);
|
||||||
// and when it's done, execute callback
|
|
||||||
call_user_func($callback, $this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,28 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\Pool\Tests;
|
namespace DesignPatterns\Creational\Pool\Tests;
|
||||||
|
|
||||||
use DesignPatterns\Creational\Pool\Pool;
|
use DesignPatterns\Creational\Pool\WorkerPool;
|
||||||
|
|
||||||
class PoolTest extends \PHPUnit_Framework_TestCase
|
class PoolTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testPool()
|
public function testCanGetNewInstancesWithGet()
|
||||||
{
|
{
|
||||||
$pool = new Pool('DesignPatterns\Creational\Pool\Tests\TestWorker');
|
$pool = new WorkerPool();
|
||||||
$worker = $pool->get();
|
$worker1 = $pool->get();
|
||||||
|
$worker2 = $pool->get();
|
||||||
|
|
||||||
$this->assertEquals(1, $worker->id);
|
$this->assertCount(2, $pool);
|
||||||
|
$this->assertNotSame($worker1, $worker2);
|
||||||
|
}
|
||||||
|
|
||||||
$worker->id = 5;
|
public function testCanGetSameInstanceTwiceWhenDisposingItFirst()
|
||||||
$pool->dispose($worker);
|
{
|
||||||
|
$pool = new WorkerPool();
|
||||||
|
$worker1 = $pool->get();
|
||||||
|
$pool->dispose($worker1);
|
||||||
|
$worker2 = $pool->get();
|
||||||
|
|
||||||
$this->assertEquals(5, $pool->get()->id);
|
$this->assertCount(1, $pool);
|
||||||
$this->assertEquals(1, $pool->get()->id);
|
$this->assertSame($worker1, $worker2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,29 +2,43 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\Pool;
|
namespace DesignPatterns\Creational\Pool;
|
||||||
|
|
||||||
class Pool
|
class WorkerPool implements \Countable
|
||||||
{
|
{
|
||||||
private $instances = [];
|
/**
|
||||||
|
* @var StringReverseWorker[]
|
||||||
|
*/
|
||||||
|
private $occupiedWorkers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var StringReverseWorker[]
|
||||||
|
*/
|
||||||
|
private $freeWorkers = [];
|
||||||
|
|
||||||
private $class;
|
public function get(): StringReverseWorker
|
||||||
|
|
||||||
public function __construct($class)
|
|
||||||
{
|
{
|
||||||
$this->class = $class;
|
if (count($this->freeWorkers) == 0) {
|
||||||
}
|
$worker = new StringReverseWorker();
|
||||||
|
} else {
|
||||||
public function get()
|
$worker = array_pop($this->freeWorkers);
|
||||||
{
|
|
||||||
if (count($this->instances) > 0) {
|
|
||||||
return array_pop($this->instances);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user