mirror of
https://github.com/Icinga/icingadb-web.git
synced 2026-05-28 04:36:06 -04:00
Make Icinga\Module\Icingadb\Common\IcingaRedis a singleton
This limits the connection attempts and established connections to a single one. Previously we made as many as we've accessed redis.
This commit is contained in:
parent
fcda9bd655
commit
2b480c881d
7 changed files with 39 additions and 33 deletions
|
|
@ -20,8 +20,6 @@ use Zend_Validate_Callback;
|
|||
|
||||
class RedisConfigForm extends ConfigForm
|
||||
{
|
||||
use IcingaRedis;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
|
|
@ -482,7 +480,7 @@ class RedisConfigForm extends ConfigForm
|
|||
$redisConfig->setSection('redis2', $sections['redis2'] ?? []);
|
||||
|
||||
try {
|
||||
$redis1 = $form->getPrimaryRedis($moduleConfig, $redisConfig);
|
||||
$redis1 = IcingaRedis::getPrimaryRedis($moduleConfig, $redisConfig);
|
||||
} catch (Exception $e) {
|
||||
$form->warning(sprintf(
|
||||
t('Failed to connect to primary Redis: %s'),
|
||||
|
|
@ -491,19 +489,19 @@ class RedisConfigForm extends ConfigForm
|
|||
return false;
|
||||
}
|
||||
|
||||
if ($form->getLastIcingaHeartbeat($redis1) === null) {
|
||||
if (IcingaRedis::getLastIcingaHeartbeat($redis1) === null) {
|
||||
$form->warning(t('Primary connection established but failed to verify Icinga is connected as well.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$redis2 = $form->getSecondaryRedis($moduleConfig, $redisConfig);
|
||||
$redis2 = IcingaRedis::getSecondaryRedis($moduleConfig, $redisConfig);
|
||||
} catch (Exception $e) {
|
||||
$form->warning(sprintf(t('Failed to connect to secondary Redis: %s'), $e->getMessage()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($redis2 !== null && $form->getLastIcingaHeartbeat($redis2) === null) {
|
||||
if ($redis2 !== null && IcingaRedis::getLastIcingaHeartbeat($redis2) === null) {
|
||||
$form->warning(t('Secondary connection established but failed to verify Icinga is connected as well.'));
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,28 @@ use Exception;
|
|||
use Icinga\Application\Config;
|
||||
use Predis\Client as Redis;
|
||||
|
||||
trait IcingaRedis
|
||||
class IcingaRedis
|
||||
{
|
||||
/** @var static The singleton */
|
||||
protected static $instance;
|
||||
|
||||
/** @var Redis Connection to the Icinga Redis */
|
||||
private $redis;
|
||||
|
||||
/**
|
||||
* Get the singleton
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function instance(): self
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new static();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection to the Icinga Redis
|
||||
*
|
||||
|
|
@ -20,7 +37,7 @@ trait IcingaRedis
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getIcingaRedis()
|
||||
public function getConnection()
|
||||
{
|
||||
if ($this->redis === null) {
|
||||
try {
|
||||
|
|
@ -63,8 +80,12 @@ trait IcingaRedis
|
|||
return $this->redis;
|
||||
}
|
||||
|
||||
public function getLastIcingaHeartbeat(Redis $redis)
|
||||
public static function getLastIcingaHeartbeat(Redis $redis = null)
|
||||
{
|
||||
if ($redis === null) {
|
||||
$redis = self::instance()->getConnection();
|
||||
}
|
||||
|
||||
// Predis doesn't support streams (yet).
|
||||
// https://github.com/predis/predis/issues/607#event-3640855190
|
||||
$rs = $redis->executeRaw(['XREAD', 'COUNT', '1', 'STREAMS', 'icinga:stats', '0']);
|
||||
|
|
@ -90,7 +111,7 @@ trait IcingaRedis
|
|||
return null;
|
||||
}
|
||||
|
||||
public function getPrimaryRedis(Config $moduleConfig = null, Config $redisConfig = null)
|
||||
public static function getPrimaryRedis(Config $moduleConfig = null, Config $redisConfig = null)
|
||||
{
|
||||
if ($moduleConfig === null) {
|
||||
$moduleConfig = Config::module('icingadb');
|
||||
|
|
@ -106,14 +127,14 @@ trait IcingaRedis
|
|||
'host' => $section->get('host', 'localhost'),
|
||||
'port' => $section->get('port', 6380),
|
||||
'timeout' => 0.5
|
||||
] + $this->getTlsParams($moduleConfig));
|
||||
] + static::getTlsParams($moduleConfig));
|
||||
|
||||
$redis->ping();
|
||||
|
||||
return $redis;
|
||||
}
|
||||
|
||||
public function getSecondaryRedis(Config $moduleConfig = null, Config $redisConfig = null)
|
||||
public static function getSecondaryRedis(Config $moduleConfig = null, Config $redisConfig = null)
|
||||
{
|
||||
if ($moduleConfig === null) {
|
||||
$moduleConfig = Config::module('redis');
|
||||
|
|
@ -134,14 +155,14 @@ trait IcingaRedis
|
|||
'host' => $host,
|
||||
'port' => $section->get('port', 6380),
|
||||
'timeout' => 0.5
|
||||
] + $this->getTlsParams($moduleConfig));
|
||||
] + static::getTlsParams($moduleConfig));
|
||||
|
||||
$redis->ping();
|
||||
|
||||
return $redis;
|
||||
}
|
||||
|
||||
private function getTlsParams(Config $config)
|
||||
private static function getTlsParams(Config $config)
|
||||
{
|
||||
$config = $config->getSection('redis');
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ use ipl\Orm\Model;
|
|||
|
||||
abstract class ObjectInspectionDetail extends BaseHtmlElement
|
||||
{
|
||||
use IcingaRedis;
|
||||
|
||||
protected $tag = 'div';
|
||||
|
||||
protected $defaultAttributes = ['class' => ['object-detail', 'inspection-detail']];
|
||||
|
|
@ -101,7 +99,7 @@ abstract class ObjectInspectionDetail extends BaseHtmlElement
|
|||
$title = new HtmlElement('h2', null, Text::create(t('Volatile State Details')));
|
||||
|
||||
try {
|
||||
$json = $this->getIcingaRedis()
|
||||
$json = IcingaRedis::instance()->getConnection()
|
||||
->hGet("icinga:{$this->object->getTableName()}:state", bin2hex($this->object->id));
|
||||
} catch (Exception $e) {
|
||||
return [$title, sprintf('Failed to load redis data: %s', $e->getMessage())];
|
||||
|
|
|
|||
|
|
@ -12,14 +12,12 @@ use ipl\Orm\Model;
|
|||
|
||||
class VolatileState implements RetrieveBehavior
|
||||
{
|
||||
use IcingaRedis;
|
||||
|
||||
protected $state;
|
||||
|
||||
protected function getVolatileState()
|
||||
{
|
||||
if ($this->state === null) {
|
||||
$this->state = new RedisState($this->getIcingaRedis());
|
||||
$this->state = new RedisState(IcingaRedis::instance()->getConnection());
|
||||
}
|
||||
|
||||
return $this->state;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ use ipl\Stdlib\Filter;
|
|||
class ApplicationState extends ApplicationStateHook
|
||||
{
|
||||
use Database;
|
||||
use IcingaRedis;
|
||||
|
||||
public function collectMessages()
|
||||
{
|
||||
|
|
@ -52,11 +51,7 @@ class ApplicationState extends ApplicationStateHook
|
|||
$outdatedDbHeartbeat = $instance->heartbeat < time() - 60;
|
||||
|
||||
try {
|
||||
$redis = $this->getIcingaRedis();
|
||||
|
||||
Session::getSession()->getNamespace('icingadb')->delete('redis.down-since');
|
||||
|
||||
$lastIcingaHeartbeat = $this->getLastIcingaHeartbeat($redis);
|
||||
$lastIcingaHeartbeat = IcingaRedis::getLastIcingaHeartbeat();
|
||||
if ($lastIcingaHeartbeat === null) {
|
||||
$missingSince = Session::getSession()
|
||||
->getNamespace('icingadb')->get('redis.heartbeat-missing-since');
|
||||
|
|
@ -93,6 +88,8 @@ class ApplicationState extends ApplicationStateHook
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
Session::getSession()->getNamespace('icingadb')->delete('redis.down-since');
|
||||
} catch (Exception $e) {
|
||||
$downSince = Session::getSession()->getNamespace('icingadb')->get('redis.down-since');
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ use Icinga\Module\Icingadb\Model\Instance;
|
|||
class RedisHealth extends HealthHook
|
||||
{
|
||||
use Database;
|
||||
use IcingaRedis;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
|
|
@ -23,9 +22,7 @@ class RedisHealth extends HealthHook
|
|||
public function checkHealth()
|
||||
{
|
||||
try {
|
||||
$redis = $this->getIcingaRedis();
|
||||
|
||||
$lastIcingaHeartbeat = $this->getLastIcingaHeartbeat($redis);
|
||||
$lastIcingaHeartbeat = IcingaRedis::getLastIcingaHeartbeat();
|
||||
if ($lastIcingaHeartbeat === null) {
|
||||
$lastIcingaHeartbeat = time();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,11 @@
|
|||
|
||||
namespace Icinga\Module\Icingadb\Setup;
|
||||
|
||||
use Icinga\Module\Icingadb\Common\IcingaRedis;
|
||||
use Icinga\Module\Icingadb\Forms\RedisConfigForm;
|
||||
use Icinga\Web\Form;
|
||||
|
||||
class RedisPage extends Form
|
||||
{
|
||||
use IcingaRedis;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->setName('setup_icingadb_redis');
|
||||
|
|
|
|||
Loading…
Reference in a new issue