diff --git a/redis.services.yml b/redis.services.yml index 4d1e023772856624de264d720556e92b0734f8fe..34f04b2fb100f43af3c95ae3b0c2a6edb7d74e1d 100644 --- a/redis.services.yml +++ b/redis.services.yml @@ -20,3 +20,6 @@ services: arguments: ['@redis.factory', '@settings'] tags: - queue_factory + queue.redis_unique: + class: Drupal\redis\Queue\UniqueQueueRedisFactory + arguments: ['@redis.factory', '@settings'] diff --git a/src/ClientFactory.php b/src/ClientFactory.php index b9b1ea01ca8a9ead96c789bdf1ac3de09941d959..dcbf8d7fd5857e0b45ea95ca54e7525a0d5b355c 100644 --- a/src/ClientFactory.php +++ b/src/ClientFactory.php @@ -63,6 +63,11 @@ class ClientFactory { */ const REDIS_IMPL_RELIABLE_QUEUE = '\\Drupal\\redis\\Queue\\Reliable'; + /** + * Unique queue implementation namespace. + */ + const REDIS_IMPL_UNIQUE_QUEUE = '\\Drupal\\redis\\Queue\\Unique'; + /** * @var \Drupal\redis\ClientInterface */ diff --git a/src/Queue/UniquePhpRedis.php b/src/Queue/UniquePhpRedis.php new file mode 100644 index 0000000000000000000000000000000000000000..a935faf78ee25f51280c40abf15b3cff9e503d50 --- /dev/null +++ b/src/Queue/UniquePhpRedis.php @@ -0,0 +1,36 @@ +<?php + +namespace Drupal\redis\Queue; + +/** + * Unique Redis queue implementation using PhpRedis extension backend. + * + * @ingroup queue + */ +class UniquePhpRedis extends PhpRedis { + + /** + * {@inheritdoc} + */ + public function createItem($data) { + $record = new \stdClass(); + $record->data = $data; + $record->qid = md5(serialize($data)); + + // We cannot rely on REQUEST_TIME because many items might be created + // by a single request which takes longer than 1 second. + $record->timestamp = time(); + + if (!$this->client->hsetnx($this->availableItems, $record->qid, serialize($record))) { + return FALSE; + } + + $start_len = $this->client->lLen($this->availableListKey); + if ($start_len < $this->client->lpush($this->availableListKey, $record->qid)) { + return $record->qid; + } + + return FALSE; + } + +} diff --git a/src/Queue/UniqueQueueRedisFactory.php b/src/Queue/UniqueQueueRedisFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..71b8b9e65404c0c14810866cd41555e6da73c12e --- /dev/null +++ b/src/Queue/UniqueQueueRedisFactory.php @@ -0,0 +1,17 @@ +<?php + +namespace Drupal\redis\Queue; + +use Drupal\redis\ClientFactory; + +/** + * Defines the unique queue factory for the Redis backend. + */ +class UniqueQueueRedisFactory extends QueueRedisFactory { + + /** + * Queue implementation class namespace prefix. + */ + const CLASS_NAMESPACE = ClientFactory::REDIS_IMPL_UNIQUE_QUEUE; + +}