Merge pull request #15982 from civicrm/5.20
[civicrm-core.git] / CRM / Queue / Service.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 * The queue service provides an interface for creating or locating
14 * queues. Note that this approach hides the details of data-storage:
15 * different queue-providers may store the queue content in different
16 * ways (in memory, in SQL, or in an external service).
17 *
18 * @code
19 * $queue = CRM_Queue_Service::singleton()->create(array(
20 * 'type' => 'interactive',
21 * 'name' => 'upgrade-tasks',
22 * ));
23 * $queue->createItem($myData);
24 *
25 * // Some time later...
26 * $item = $queue->claimItem();
5e74f823
TO
27 * if ($item) {
28 * if (my_process($item->data)) {
16e38e82 29 * $queue->deleteItem($item);
5e74f823 30 * } else {
16e38e82 31 * $queue->releaseItem($item);
5e74f823 32 * }
6a488035
TO
33 * }
34 * @endcode
35 */
36class CRM_Queue_Service {
37
4523a2f5 38 protected static $_singleton;
6a488035
TO
39
40 /**
41 * FIXME: Singleton pattern should be removed when dependency-injection
42 * becomes available.
43 *
4523a2f5
TO
44 * @param bool $forceNew
45 * TRUE if a new instance must be created.
77b97be7
EM
46 *
47 * @return \CRM_Queue_Service
6a488035 48 */
4523a2f5 49 public static function &singleton($forceNew = FALSE) {
6a488035
TO
50 if ($forceNew || !self::$_singleton) {
51 self::$_singleton = new CRM_Queue_Service();
52 }
53 return self::$_singleton;
54 }
55
56 /**
041ecc95 57 * Queues.
58 *
59 * Format is (string $queueName => CRM_Queue_Queue).
60 *
61 * @var array
6a488035 62 */
4523a2f5 63 public $queues;
e0ef6999
EM
64
65 /**
041ecc95 66 * Class constructor.
e0ef6999 67 */
4523a2f5 68 public function __construct() {
be2fb01f 69 $this->queues = [];
6a488035
TO
70 }
71
72 /**
4523a2f5
TO
73 * Create a queue. If one already exists, then it will be reused.
74 *
75 * @param array $queueSpec
76 * Array with keys:
77 * - type: string, required, e.g. "interactive", "immediate", "stomp",
78 * "beanstalk"
6a488035 79 * - name: string, required, e.g. "upgrade-tasks"
4523a2f5
TO
80 * - reset: bool, optional; if a queue is found, then it should be
81 * flushed; default to TRUE
82 * - (additional keys depending on the queue provider).
6a488035
TO
83 *
84 * @return CRM_Queue_Queue
85 */
4523a2f5 86 public function create($queueSpec) {
6a488035
TO
87 if (@is_object($this->queues[$queueSpec['name']]) && empty($queueSpec['reset'])) {
88 return $this->queues[$queueSpec['name']];
89 }
90
91 $queue = $this->instantiateQueueObject($queueSpec);
92 $exists = $queue->existsQueue();
93 if (!$exists) {
94 $queue->createQueue();
95 }
96 elseif (@$queueSpec['reset']) {
97 $queue->deleteQueue();
98 $queue->createQueue();
99 }
100 else {
101 $queue->loadQueue();
102 }
103 $this->queues[$queueSpec['name']] = $queue;
104 return $queue;
105 }
106
107 /**
4523a2f5
TO
108 * Look up an existing queue.
109 *
110 * @param array $queueSpec
111 * Array with keys:
112 * - type: string, required, e.g. "interactive", "immediate", "stomp",
113 * "beanstalk"
6a488035 114 * - name: string, required, e.g. "upgrade-tasks"
4523a2f5 115 * - (additional keys depending on the queue provider).
6a488035
TO
116 *
117 * @return CRM_Queue_Queue
118 */
4523a2f5 119 public function load($queueSpec) {
6a488035
TO
120 if (is_object($this->queues[$queueSpec['name']])) {
121 return $this->queues[$queueSpec['name']];
122 }
123 $queue = $this->instantiateQueueObject($queueSpec);
124 $queue->loadQueue();
125 $this->queues[$queueSpec['name']] = $queue;
126 return $queue;
127 }
128
129 /**
fe482240 130 * Convert a queue "type" name to a class name.
6a488035 131 *
4523a2f5
TO
132 * @param string $type
133 * E.g. "interactive", "immediate", "stomp", "beanstalk".
6a488035 134 *
4523a2f5
TO
135 * @return string
136 * Class-name
6a488035
TO
137 */
138 protected function getQueueClass($type) {
139 $type = preg_replace('/[^a-zA-Z0-9]/', '', $type);
140 $className = 'CRM_Queue_Queue_' . $type;
141 // FIXME: when used with class-autoloader, this may be unnecessary
142 if (!class_exists($className)) {
143 $classFile = 'CRM/Queue/Queue/' . $type . '.php';
144 require_once $classFile;
145 }
146 return $className;
147 }
148
149 /**
4523a2f5
TO
150 * @param array $queueSpec
151 * See create().
6a488035
TO
152 *
153 * @return CRM_Queue_Queue
154 */
155 protected function instantiateQueueObject($queueSpec) {
156 // note: you should probably never do anything else here
157 $class = new ReflectionClass($this->getQueueClass($queueSpec['type']));
158 return $class->newInstance($queueSpec);
159 }
96025800 160
6a488035 161}