Redis: Apply volatile state results directly to the state model

Since all the inconsistent column/redis key names have been renamed, we don't have to cache redis
keys separately anymore. This PR applies all the `Service/Host` volatile state results directly
to the respective state model.
This commit is contained in:
Yonas Habteab 2022-06-27 16:26:47 +02:00 committed by Johannes Meyer
parent 3321961aba
commit 9f2f4155b6
2 changed files with 14 additions and 69 deletions

View file

@ -1,65 +0,0 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Redis;
use Icinga\Module\Icingadb\Model\State;
use Predis\Client as Redis;
/**
* Fetch volatile host or service states from redis.
*/
class VolatileState
{
/** @var Redis */
protected $redis;
/** @var array Set of keys to sync */
public static $keys = [
'attempt',
'output',
'long_output',
'performance_data',
'normalized_performance_data',
'check_commandline',
'execution_time',
'latency',
'timeout',
'last_update',
'next_check',
'next_update'
];
/**
* VolatileState constructor.
*
* @param Redis $redis Connection to the Icinga Redis
*/
public function __construct(Redis $redis)
{
$this->redis = $redis;
}
/**
* Fetch volatile state
*
* @param State $state
*
* @return $this
*/
public function fetch(State $state): self
{
$type = substr($state->getTableName(), 0, -6);
$json = $this->redis->hGet("icinga:{$type}:state", bin2hex($state->{$type . '_id'}));
if ($json !== null) {
$data = json_decode($json, true);
$data = array_intersect_key($data, array_flip(static::$keys));
$state->setProperties($data);
}
return $this;
}
}

View file

@ -67,6 +67,9 @@ class VolatileStateResults extends ResultSet
$type = null;
$behaviors = null;
$keys = [];
$hostStateKeys = [];
$states = [];
$hostStates = [];
foreach ($this as $row) {
@ -86,8 +89,15 @@ class VolatileStateResults extends ResultSet
}
$states[bin2hex($row->id)] = $row->state;
if (empty($keys)) {
$keys = $row->state->getColumns();
}
if ($type === 'service' && $row->host instanceof Host) {
$hostStates[bin2hex($row->host->id)] = $row->host->state;
if (empty($hostStateKeys)) {
$hostStateKeys = $row->host->state->getColumns();
}
}
}
@ -95,7 +105,7 @@ class VolatileStateResults extends ResultSet
return;
}
foreach ($this->fetchStates("icinga:{$type}:state", array_keys($states)) as $id => $data) {
foreach ($this->fetchStates("icinga:{$type}:state", array_keys($states), $keys) as $id => $data) {
foreach ($data as $key => $value) {
$data[$key] = $behaviors->retrieveProperty($value, $key);
}
@ -104,7 +114,7 @@ class VolatileStateResults extends ResultSet
}
if ($type === 'service' && ! empty($hostStates)) {
foreach ($this->fetchStates('icinga:host:state', array_keys($hostStates)) as $id => $data) {
foreach ($this->fetchStates('icinga:host:state', array_keys($hostStates), $hostStateKeys) as $id => $data) {
foreach ($data as $key => $value) {
$data[$key] = $behaviors->retrieveProperty($value, $key);
}
@ -114,13 +124,13 @@ class VolatileStateResults extends ResultSet
}
}
protected function fetchStates(string $key, array $ids): Generator
protected function fetchStates(string $key, array $ids, array $keys): Generator
{
$results = IcingaRedis::instance()->getConnection()->hmget($key, $ids);
foreach ($results as $i => $json) {
if ($json !== null) {
$data = json_decode($json, true);
$data = array_intersect_key($data, array_flip(VolatileState::$keys));
$data = array_intersect_key(array_merge(array_fill_keys($keys, null), $data), array_flip($keys));
yield $ids[$i] => $data;
}