From feefeb9b357c0393b2b3fdb85ac042727c54b0f6 Mon Sep 17 00:00:00 2001 From: Eloy Villasclaras Fernandez Date: Wed, 4 Jul 2018 11:50:45 +0100 Subject: [PATCH] Added support for FIFO flatfile driver --- src/Driver/FlatFile/Driver.php | 13 ++- tests/Driver/FlatFile/FifoDriverTest.php | 134 +++++++++++++++++++++++ 2 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 tests/Driver/FlatFile/FifoDriverTest.php diff --git a/src/Driver/FlatFile/Driver.php b/src/Driver/FlatFile/Driver.php index c1df5cfc..85e340e2 100644 --- a/src/Driver/FlatFile/Driver.php +++ b/src/Driver/FlatFile/Driver.php @@ -14,14 +14,17 @@ class Driver implements \Bernard\Driver private $permissions; + private $queueType; + /** * @param string $baseDirectory The base directory * @param int $permissions permissions to create the file with */ - public function __construct($baseDirectory, $permissions = 0740) + public function __construct($baseDirectory, $permissions = 0740, $options = null) { $this->baseDirectory = $baseDirectory; $this->permissions = $permissions; + $this->queueType = isset($options['queueType']) && in_array($options['queueType'], ['lifo', 'fifo']) ? $options['queueType'] : 'lifo'; } /** @@ -101,7 +104,7 @@ public function popMessage($queueName, $duration = 5) while (microtime(true) < $runtime) { if ($files) { - $id = array_pop($files); + $id = $this->queueType === 'fifo' ? array_shift($files) : array_pop($files); if (@rename($queueDir.DIRECTORY_SEPARATOR.$id, $queueDir.DIRECTORY_SEPARATOR.$id.'.proceed')) { return [file_get_contents($queueDir.DIRECTORY_SEPARATOR.$id.'.proceed'), $id]; } @@ -118,7 +121,7 @@ public function popMessage($queueName, $duration = 5) /** * @param string $queueDir * @param string $id - * + * * @return array */ private function processFileOrFail($queueDir, $id) { @@ -158,7 +161,9 @@ public function peekQueue($queueName, $index = 0, $limit = 20) $files = array_keys(iterator_to_array($it)); natsort($files); - $files = array_reverse($files); + if ($this->queueType === 'life') { + $files = array_reverse($files); + } $files = array_slice($files, $index, $limit); diff --git a/tests/Driver/FlatFile/FifoDriverTest.php b/tests/Driver/FlatFile/FifoDriverTest.php new file mode 100644 index 00000000..0c98b92f --- /dev/null +++ b/tests/Driver/FlatFile/FifoDriverTest.php @@ -0,0 +1,134 @@ + + */ +class FifoDriverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Driver + */ + private $driver; + + protected function setUp() + { + $this->baseDir = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'bernard-flat'; + + if (!is_dir($this->baseDir)) { + mkdir($this->baseDir, 0777, true); + } + + $this->driver = new Driver($this->baseDir, 0740, ['queueType' => 'fifo']); + } + + protected function tearDown() + { + if ((strtoupper(substr(\PHP_OS, 0, 3)) === 'WIN')) { + system('rd /s /q '.$this->baseDir); + } else { + system('rm -R '.$this->baseDir); + } + } + + public function testCreate() + { + $this->driver->createQueue('send-newsletter'); + $this->driver->createQueue('send-newsletter'); + + $this->assertDirectoryExists($this->baseDir.\DIRECTORY_SEPARATOR.'send-newsletter'); + } + + public function testRemove() + { + $this->driver->createQueue('send-newsletter'); + $this->driver->pushMessage('send-newsletter', 'test'); + + $this->driver->removeQueue('send-newsletter'); + + $this->assertDirectoryNotExists($this->baseDir.\DIRECTORY_SEPARATOR.'send-newsletter'); + } + + public function testRemoveQueueWithPoppedMessage() + { + $this->driver->createQueue('send-newsletter'); + $this->driver->pushMessage('send-newsletter', 'test'); + $this->driver->popMessage('send-newsletter'); + + $this->driver->removeQueue('send-newsletter'); + + $this->assertDirectoryNotExists($this->baseDir.\DIRECTORY_SEPARATOR.'send-newsletter'); + } + + public function testPushMessage() + { + $this->driver->createQueue('send-newsletter'); + $this->driver->pushMessage('send-newsletter', 'test'); + + $this->assertCount(1, glob($this->baseDir.\DIRECTORY_SEPARATOR.'send-newsletter'.\DIRECTORY_SEPARATOR.'*.job')); + } + + public function testPushMessagePermissions() + { + $this->driver = new Driver($this->baseDir, 0770); + $this->testPushMessage(); + $this->assertEquals('0770', substr(sprintf('%o', fileperms($this->baseDir.\DIRECTORY_SEPARATOR.'send-newsletter'.\DIRECTORY_SEPARATOR.'1.job')), -4)); + } + + public function testPopMessage() + { + $this->driver->createQueue('send-newsletter'); + + $this->driver->pushMessage('send-newsletter', 'job #1'); + $this->driver->pushMessage('send-newsletter', 'job #2'); + $this->driver->pushMessage('send-newsletter', 'job #3'); + + foreach (range(1, 3) as $i) { + list($message) = $this->driver->popMessage('send-newsletter'); + $this->assertEquals('job #'.$i, $message); + } + } + + public function testAcknowledgeMessage() + { + $this->driver->createQueue('send-newsletter'); + + $this->driver->pushMessage('send-newsletter', 'job #1'); + + $message = $this->driver->popMessage('send-newsletter'); + + $this->driver->acknowledgeMessage('send-newsletter', $message[1]); + + $this->assertCount(0, glob($this->baseDir.\DIRECTORY_SEPARATOR.'send-newsletter'.\DIRECTORY_SEPARATOR.'*.job')); + } + + public function testPeekQueue() + { + $this->driver->createQueue('send-newsletter'); + + for ($i = 0; $i < 10; ++$i) { + $this->driver->pushMessage('send-newsletter', 'Job #'.$i); + } + + $this->assertCount(3, $this->driver->peekQueue('send-newsletter', 0, 3)); + + $this->assertCount(10, glob($this->baseDir.\DIRECTORY_SEPARATOR.'send-newsletter'.\DIRECTORY_SEPARATOR.'*.job')); + } + + public function testListQueues() + { + $this->driver->createQueue('send-newsletter-1'); + + $this->driver->createQueue('send-newsletter-2'); + $this->driver->pushMessage('send-newsletter-2', 'job #1'); + + $this->driver->createQueue('send-newsletter-3'); + $this->driver->pushMessage('send-newsletter-3', 'job #1'); + $this->driver->pushMessage('send-newsletter-3', 'job #2'); + + $this->assertCount(3, $this->driver->listQueues()); + } +}