From ef67b71353ea4815ef1e4fdbc67e0d48d791ee17 Mon Sep 17 00:00:00 2001 From: Jared Hancock <gravydish@gmail.com> Date: Tue, 14 Aug 2018 03:51:32 +0000 Subject: [PATCH] queues: cache queue counts If APCu is available, then the queue counts can be cached between requests. They are automatically cleared and recalculated if the status of a ticket changes or if a queue or saved search is edited. Otherwise, the queue counts will expire after an hour and be recalculated anyway. --- include/class.queue.php | 5 ++++- include/class.search.php | 28 ++++++++++++++++++++++++++-- include/class.ticket.php | 3 +++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/class.queue.php b/include/class.queue.php index b35f33b85..e62300017 100644 --- a/include/class.queue.php +++ b/include/class.queue.php @@ -1299,8 +1299,11 @@ class CustomQueue extends VerySimpleModel { $nopath = !isset($this->path); $path_changed = isset($this->dirty['parent_id']); - if ($this->dirty) + if ($this->dirty) { $this->updated = SqlFunction::NOW(); + // Refetch the queue counts + SavedQueue::clearCounts(); + } if (!($rv = parent::save($refetch || $this->dirty))) return $rv; diff --git a/include/class.search.php b/include/class.search.php index eb720bcc2..6dad61416 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -854,7 +854,15 @@ class SavedQueue extends CustomQueue { if (!$agent instanceof Staff) return array(); - $queues = SavedQueue::objects() + if (function_exists('apcu_store')) { + $key = "counts.queues.{$agent->getId()}.".SECRET_SALT; + $cached = false; + $counts = apcu_fetch($key, $cached); + if ($cached === true) + return $counts; + } + + $queues = static::objects() ->filter(Q::any(array( 'flags__hasbit' => CustomQueue::FLAG_QUEUE, 'staff_id' => $agent->getId(), @@ -875,7 +883,23 @@ class SavedQueue extends CustomQueue { )); } - return $query->values()->one(); + $counts = $query->values()->one(); + + if (function_exists('apcu_store')) { + $key = "counts.queues.{$agent->getId()}.".SECRET_SALT; + apcu_store($key, $counts, 3600); + } + + return $counts; + } + + static function clearCounts() { + if (function_exists('apcu_store')) { + $regex = '/^counts.queues.\d+.' . preg_quote(SECRET_SALT, '/') . '$/'; + foreach (new APCUIterator($regex, APC_ITER_KEY) as $key) { + apcu_delete($key); + } + } } static function lookup($criteria) { diff --git a/include/class.ticket.php b/include/class.ticket.php index 9db2bff77..37c80c73c 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -3200,6 +3200,9 @@ implements RestrictedAccess, Threadable, Searchable { function save($refetch=false) { if ($this->dirty) { $this->updated = SqlFunction::NOW(); + if (isset($this->dirty['status_id'])) + // Refetch the queue counts + SavedQueue::clearCounts(); } return parent::save($this->dirty || $refetch); } -- GitLab