mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-02-22 08:33:58 +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`_
|
||||
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user