Merge pull request #17640 from samuelsov/bugreportcivigrant
[civicrm-core.git] / CRM / Queue / Queue / Memory.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 * A queue implementation which stores items in the CiviCRM SQL database
14 */
15class CRM_Queue_Queue_Memory extends CRM_Queue_Queue {
16
17 /**
4523a2f5
TO
18 * @var array
19 * array(queueItemId => queueItemData)
6a488035 20 */
4523a2f5 21 public $items;
6a488035
TO
22
23 /**
4523a2f5
TO
24 * @var array
25 * array(queueItemId => releaseTime), expressed in seconds since epoch.
6a488035 26 */
4523a2f5 27 public $releaseTimes;
6a488035 28
4523a2f5 29 public $nextQueueItemId = 1;
6a488035
TO
30
31 /**
32 * Create a reference to queue. After constructing the queue, one should
33 * usually call createQueue (if it's a new queue) or loadQueue (if it's
34 * known to be an existing queue).
35 *
4523a2f5
TO
36 * @param array $queueSpec
37 * Array with keys:
38 * - type: string, required, e.g. "interactive", "immediate", "stomp",
39 * "beanstalk"
6a488035 40 * - name: string, required, e.g. "upgrade-tasks"
4523a2f5
TO
41 * - reset: bool, optional; if a queue is found, then it should be
42 * flushed; default to TRUE
43 * - (additional keys depending on the queue provider).
6a488035 44 */
4523a2f5 45 public function __construct($queueSpec) {
6a488035
TO
46 parent::__construct($queueSpec);
47 }
48
49 /**
50 * Perform any registation or resource-allocation for a new queue
51 */
4523a2f5 52 public function createQueue() {
be2fb01f
CW
53 $this->items = [];
54 $this->releaseTimes = [];
6a488035
TO
55 }
56
57 /**
58 * Perform any loading or pre-fetch for an existing queue.
59 */
4523a2f5 60 public function loadQueue() {
6a488035
TO
61 // $this->createQueue();
62 throw new Exception('Unsupported: CRM_Queue_Queue_Memory::loadQueue');
63 }
64
65 /**
66 * Release any resources claimed by the queue (memory, DB rows, etc)
67 */
4523a2f5 68 public function deleteQueue() {
6a488035
TO
69 $this->items = NULL;
70 $this->releaseTimes = NULL;
71 }
72
73 /**
fe482240 74 * Check if the queue exists.
6a488035
TO
75 *
76 * @return bool
77 */
4523a2f5 78 public function existsQueue() {
6a488035
TO
79 return is_array($this->items);
80 }
81
82 /**
fe482240 83 * Add a new item to the queue.
6a488035 84 *
4523a2f5
TO
85 * @param mixed $data
86 * Serializable PHP object or array.
87 * @param array $options
88 * Queue-dependent options; for example, if this is a
89 * priority-queue, then $options might specify the item's priority.
6a488035 90 */
be2fb01f 91 public function createItem($data, $options = []) {
6a488035
TO
92 $id = $this->nextQueueItemId++;
93 // force copy, no unintendedsharing effects from pointers
94 $this->items[$id] = serialize($data);
95 }
96
97 /**
fe482240 98 * Determine number of items remaining in the queue.
6a488035
TO
99 *
100 * @return int
101 */
4523a2f5 102 public function numberOfItems() {
6a488035
TO
103 return count($this->items);
104 }
105
106 /**
fe482240 107 * Get and remove the next item.
6a488035 108 *
4523a2f5
TO
109 * @param int $leaseTime
110 * Seconds.
6a488035 111 *
4523a2f5
TO
112 * @return object
113 * Includes key 'data' that matches the inputted data.
6a488035 114 */
4523a2f5 115 public function claimItem($leaseTime = 3600) {
6a488035
TO
116 // foreach hits the items in order -- but we short-circuit after the first
117 foreach ($this->items as $id => $data) {
118 $nowEpoch = CRM_Utils_Time::getTimeRaw();
119 if (empty($this->releaseTimes[$id]) || $this->releaseTimes[$id] < $nowEpoch) {
120 $this->releaseTimes[$id] = $nowEpoch + $leaseTime;
121
353ffa53
TO
122 $item = new stdClass();
123 $item->id = $id;
6a488035
TO
124 $item->data = unserialize($data);
125 return $item;
126 }
127 else {
128 // item in queue is reserved
129 return FALSE;
130 }
131 }
132 // nothing in queue
133 return FALSE;
134 }
135
136 /**
fe482240 137 * Get the next item.
6a488035 138 *
4523a2f5
TO
139 * @param int $leaseTime
140 * Seconds.
6a488035 141 *
4523a2f5
TO
142 * @return object
143 * With key 'data' that matches the inputted data.
6a488035 144 */
4523a2f5 145 public function stealItem($leaseTime = 3600) {
6a488035
TO
146 // foreach hits the items in order -- but we short-circuit after the first
147 foreach ($this->items as $id => $data) {
148 $nowEpoch = CRM_Utils_Time::getTimeRaw();
149 $this->releaseTimes[$id] = $nowEpoch + $leaseTime;
150
353ffa53
TO
151 $item = new stdClass();
152 $item->id = $id;
6a488035
TO
153 $item->data = unserialize($data);
154 return $item;
155 }
156 // nothing in queue
157 return FALSE;
158 }
159
160 /**
fe482240 161 * Remove an item from the queue.
6a488035 162 *
4523a2f5
TO
163 * @param object $item
164 * The item returned by claimItem.
6a488035 165 */
4523a2f5 166 public function deleteItem($item) {
6a488035
TO
167 unset($this->items[$item->id]);
168 unset($this->releaseTimes[$item->id]);
169 }
170
171 /**
fe482240 172 * Return an item that could not be processed.
6a488035 173 *
4523a2f5
TO
174 * @param CRM_Core_DAO $item
175 * The item returned by claimItem.
6a488035 176 */
4523a2f5 177 public function releaseItem($item) {
6a488035
TO
178 unset($this->releaseTimes[$item->id]);
179 }
96025800 180
6a488035 181}