- added _Redis_ info panel to /setup page for basic monitoring, closed #686
- improved "system index" build procedure, #666
This commit is contained in:
@@ -144,12 +144,22 @@ class Universe extends Controller {
|
||||
* @var $system Model\Universe\SystemModel
|
||||
*/
|
||||
$system = Model\Universe\BasicUniverseModel::getNew('SystemModel');
|
||||
$indexData = [];
|
||||
foreach($systemIds as $systemId){
|
||||
$system->getById($systemId);
|
||||
$system->buildIndex();
|
||||
$system->reset();
|
||||
if($hashKeyId = $system->getHashKey()){
|
||||
$indexData[$hashKeyId] = $system->getData();
|
||||
}
|
||||
// offset must increase otherwise we get a endless loop
|
||||
// -> see /setup ajax build loop function
|
||||
$offset++;
|
||||
}
|
||||
|
||||
$this->getF3()->mset($indexData, '', $system::CACHE_INDEX_EXPIRE_KEY);
|
||||
|
||||
// ... add hashKeys for all table rows to tableIndex as well
|
||||
$system::buildTableIndex($system, array_keys($indexData));
|
||||
|
||||
return ['countAll' => $systemsAll, 'countBuild' => count($systemIds), 'offset' => $offset];
|
||||
}
|
||||
|
||||
@@ -179,15 +189,16 @@ class Universe extends Controller {
|
||||
|
||||
/**
|
||||
* get complete system index (all systems)
|
||||
* @param bool $all
|
||||
* @return array
|
||||
*/
|
||||
public function getSystemsIndex() : array {
|
||||
public function getSystemsIndex(bool $all = false) : array {
|
||||
$index = [];
|
||||
$cacheKeyTable = Model\Universe\BasicUniverseModel::generateHashKeyTable('system');
|
||||
if($this->getF3()->exists($cacheKeyTable,$cacheKeys)){
|
||||
foreach((array)$cacheKeys as $cacheKeyRow){
|
||||
if(($data = $this->get($cacheKeyRow)) && is_object($data)){
|
||||
$index[$data->id] = $data;
|
||||
$index[] = $all ? $data : $data->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,13 +166,7 @@ class Setup extends Controller {
|
||||
$f3->set('tplJsView', 'setup');
|
||||
|
||||
// set render functions (called within template)
|
||||
$f3->set('cacheType', function(){
|
||||
$cacheType = $this->getF3()->get('CACHE');
|
||||
if( strpos($cacheType, 'redis') !== false ){
|
||||
$cacheType = 'redis';
|
||||
}
|
||||
return $cacheType;
|
||||
});
|
||||
$f3->set('cacheType', $this->getCacheType($f3));
|
||||
|
||||
// simple counter (called within template)
|
||||
$counter = 0;
|
||||
@@ -188,6 +182,19 @@ class Setup extends Controller {
|
||||
echo \Template::instance()->render( Config::getPathfinderData('view.index') );
|
||||
}
|
||||
|
||||
/**
|
||||
* get Cache backend type for F3
|
||||
* @param \Base $f3
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheType(\Base &$f3) : string {
|
||||
$cacheType = $f3->get('CACHE');
|
||||
if(strpos($cacheType, 'redis') !== false){
|
||||
$cacheType = 'redis';
|
||||
}
|
||||
return $cacheType;
|
||||
}
|
||||
|
||||
/**
|
||||
* main setup route handler
|
||||
* works as dispatcher for setup functions
|
||||
@@ -255,6 +262,9 @@ class Setup extends Controller {
|
||||
|
||||
// set cache size
|
||||
$f3->set('cacheSize', $this->getCacheData($f3));
|
||||
|
||||
// set Redis config check information
|
||||
$f3->set('checkRedisConfig', $this->checkRedisConfig($f3));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,8 +347,8 @@ class Setup extends Controller {
|
||||
'value' => $f3->get('PORT')
|
||||
],
|
||||
'protocol' => [
|
||||
'label' => 'Protocol',
|
||||
'value' => strtoupper( $f3->get('SCHEME') )
|
||||
'label' => 'Protocol - scheme',
|
||||
'value' => $f3->get('SERVER.SERVER_PROTOCOL') . ' - ' . $f3->get('SCHEME')
|
||||
]
|
||||
];
|
||||
|
||||
@@ -431,11 +441,8 @@ class Setup extends Controller {
|
||||
'version' => (extension_loaded('curl') && function_exists('curl_version')) ? 'installed' : 'missing',
|
||||
'check' => (extension_loaded('curl') && function_exists('curl_version'))
|
||||
],
|
||||
[
|
||||
'label' => 'Redis Server [optional]'
|
||||
],
|
||||
'ext_redis' => [
|
||||
'label' => 'Redis',
|
||||
'label' => 'Redis [optional]',
|
||||
'required' => $f3->get('REQUIREMENTS.PHP.REDIS'),
|
||||
'version' => extension_loaded('redis') ? phpversion('redis') : 'missing',
|
||||
'check' => version_compare( phpversion('redis'), $f3->get('REQUIREMENTS.PHP.REDIS'), '>='),
|
||||
@@ -593,6 +600,81 @@ class Setup extends Controller {
|
||||
return $phpConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* check Redis (cache) config
|
||||
* -> only visible if Redis is used as Cache backend
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function checkRedisConfig(\Base $f3): array {
|
||||
$redisConfig = [];
|
||||
if($this->getCacheType($f3) === 'redis'){
|
||||
// we need to access the "protected" member $ref from F3´s Cache class
|
||||
// to get access to the underlying Redis() class
|
||||
$ref = new \ReflectionObject($cache = \Cache::instance());
|
||||
$prop = $ref->getProperty('ref');
|
||||
$prop->setAccessible(true);
|
||||
/**
|
||||
* @var $redis \Redis
|
||||
*/
|
||||
$redis = $prop->getValue($cache);
|
||||
|
||||
$redisServerInfo = (array)$redis->info('SERVER');
|
||||
$redisMemoryInfo = (array)$redis->info('MEMORY');
|
||||
$redisStatsInfo = (array)$redis->info('STATS');
|
||||
|
||||
$redisConfig = [
|
||||
'redisVersion' => [
|
||||
'label' => 'redis_version',
|
||||
'required' => number_format((float)$f3->get('REQUIREMENTS.REDIS.VERSION'), 1, '.', ''),
|
||||
'version' => $redisServerInfo['redis_version'],
|
||||
'check' => version_compare( $redisServerInfo['redis_version'], $f3->get('REQUIREMENTS.REDIS.VERSION'), '>='),
|
||||
'tooltip' => 'Redis server version'
|
||||
],
|
||||
'maxMemory' => [
|
||||
'label' => 'maxmemory',
|
||||
'required' => $this->convertBytes($f3->get('REQUIREMENTS.REDIS.MAX_MEMORY')),
|
||||
'version' => $this->convertBytes($redisMemoryInfo['maxmemory']),
|
||||
'check' => $redisMemoryInfo['maxmemory'] >= $f3->get('REQUIREMENTS.REDIS.MAX_MEMORY'),
|
||||
'tooltip' => 'Max memory limit for Redis'
|
||||
],
|
||||
'usedMemory' => [
|
||||
'label' => 'used_memory',
|
||||
'version' => $this->convertBytes($redisMemoryInfo['used_memory']),
|
||||
'check' => $redisMemoryInfo['used_memory'] < $redisMemoryInfo['maxmemory'],
|
||||
'tooltip' => 'Current memory used by Redis'
|
||||
],
|
||||
'usedMemoryPeak' => [
|
||||
'label' => 'used_memory_peak',
|
||||
'version' => $this->convertBytes($redisMemoryInfo['used_memory_peak']),
|
||||
'check' => $redisMemoryInfo['used_memory_peak'] <= $redisMemoryInfo['maxmemory'],
|
||||
'tooltip' => 'Peak memory used by Redis'
|
||||
],
|
||||
'maxmemoryPolicy' => [
|
||||
'label' => 'maxmemory_policy',
|
||||
'required' => $f3->get('REQUIREMENTS.REDIS.MAXMEMORY_POLICY'),
|
||||
'version' => $redisMemoryInfo['maxmemory_policy'],
|
||||
'check' => $redisMemoryInfo['maxmemory_policy'] == $f3->get('REQUIREMENTS.REDIS.MAXMEMORY_POLICY'),
|
||||
'tooltip' => 'How Redis behaves if \'maxmemory\' limit reached'
|
||||
],
|
||||
'evictedKeys' => [
|
||||
'label' => 'evicted_keys',
|
||||
'version' => $redisStatsInfo['evicted_keys'],
|
||||
'check' => !(bool)$redisStatsInfo['evicted_keys'],
|
||||
'tooltip' => 'Number of evicted keys due to maxmemory limit'
|
||||
],
|
||||
'dbSize' . $redis->getDbNum() => [
|
||||
'label' => 'Size DB (' . $redis->getDbNum() . ')',
|
||||
'version' => $redis->dbSize(),
|
||||
'check' => $redis->dbSize() > 0,
|
||||
'tooltip' => 'Keys found in DB (' . $redis->getDbNum() . ') [Cache DB]'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $redisConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* check system environment vars
|
||||
* -> mostly relevant for development/build/deployment
|
||||
@@ -1419,8 +1501,8 @@ class Setup extends Controller {
|
||||
$result = '0';
|
||||
if($bytes){
|
||||
$base = log($bytes, 1024);
|
||||
$suffixes = array('', 'KB', 'MB', 'GB', 'TB');
|
||||
$result = round(pow(1024, $base - floor($base)), $precision) .' '. $suffixes[floor($base)];
|
||||
$suffixes = array('', 'KB', 'M', 'GB', 'TB');
|
||||
$result = round(pow(1024, $base - floor($base)), $precision) .''. $suffixes[floor($base)];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -100,28 +100,32 @@ abstract class BasicUniverseModel extends BasicModel {
|
||||
*/
|
||||
public function buildIndex(){
|
||||
$data = null;
|
||||
|
||||
if($hashKeyId = $this->getHashKey()){
|
||||
$hashKeyTable = self::generateHashKeyTable($this->getTable());
|
||||
|
||||
if( !self::existsCacheValue($hashKeyTable, $cachedData) ){
|
||||
$cachedData = [];
|
||||
}
|
||||
|
||||
if( !in_array($hashKeyId, $cachedData) ){
|
||||
$cachedData[] = $hashKeyId;
|
||||
}
|
||||
|
||||
$data = $this->getData();
|
||||
$this->getF3()->set($hashKeyId, $data, self::CACHE_INDEX_EXPIRE_KEY);
|
||||
|
||||
// straight into cache (no $f->set() ), no sync with hive here -> save ram
|
||||
self::setCacheValue($hashKeyId, $data, self::CACHE_INDEX_EXPIRE_KEY);
|
||||
self::setCacheValue($hashKeyTable, $cachedData, self::CACHE_INDEX_EXPIRE_KEY);
|
||||
// ... add hashKey for this rows to tableIndex as well
|
||||
self::buildTableIndex($this, [$hashKeyId]);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add $rowKeys (hashKeys) to a search index that holds all rowKeys of a table
|
||||
* @param BasicUniverseModel $model
|
||||
* @param array $rowKeys
|
||||
*/
|
||||
public static function buildTableIndex(BasicUniverseModel $model, array $rowKeys = []){
|
||||
$hashKeyTable = self::generateHashKeyTable($model->getTable());
|
||||
if( !self::getF3()->exists($hashKeyTable, $cachedData) ){
|
||||
$cachedData = [];
|
||||
}
|
||||
$cachedData = array_unique(array_merge($cachedData, $rowKeys));
|
||||
|
||||
self::getF3()->set($hashKeyTable, $cachedData, self::CACHE_INDEX_EXPIRE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* get data from "search" index for this model
|
||||
* -> if data not found -> try to build up index for this model
|
||||
|
||||
@@ -9,7 +9,6 @@ APACHE.VERSION = 2.5
|
||||
NGINX.VERSION = 1.9
|
||||
|
||||
[REQUIREMENTS.PHP]
|
||||
; recommended is >= 5.6
|
||||
VERSION = 7.0
|
||||
|
||||
; 64-bit version of PHP (4 = 32-bit, 8 = 64-bit)
|
||||
@@ -50,7 +49,6 @@ MAX_INPUT_VARS = 3000
|
||||
HTML_ERRORS = 0
|
||||
|
||||
[REQUIREMENTS.LIBS]
|
||||
|
||||
ZMQ = 4.1.3
|
||||
|
||||
[REQUIREMENTS.MYSQL]
|
||||
@@ -72,6 +70,14 @@ COLLATION_DATABASE = utf8_general_ci
|
||||
COLLATION_CONNECTION = utf8_general_ci
|
||||
FOREIGN_KEY_CHECKS = ON
|
||||
|
||||
[REQUIREMENTS.REDIS]
|
||||
VERSION = 3.0
|
||||
; max memory limit (Bytes) "binary" (default: 128M)
|
||||
MAX_MEMORY = 134217728
|
||||
; how Redis behaves if "maxmemory" limit reached
|
||||
; https://redis.io/topics/lru-cache
|
||||
MAXMEMORY_POLICY = allkeys-lru
|
||||
|
||||
[REQUIREMENTS.PATH]
|
||||
NODE = 6.0
|
||||
NPM = 3.10.0
|
||||
|
||||
@@ -142,10 +142,8 @@
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-md-6 pf-landing-pricing-panel">
|
||||
|
||||
{* Server *}
|
||||
<div class="panel panel-default pricing-big">
|
||||
|
||||
<div class="panel-heading text-left">
|
||||
<h3 class="panel-title">Server</h3>
|
||||
</div>
|
||||
@@ -166,6 +164,30 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* System Env requirements *}
|
||||
<check if="{{ @checkSystemConfig }}">
|
||||
<set requirementsData="{{ @checkSystemConfig }}" />
|
||||
|
||||
<div class="panel panel-default pricing-big">
|
||||
<div class="panel-heading text-left">
|
||||
<h3 class="panel-title">Environment variables [optional]</h3>
|
||||
</div>
|
||||
<div class="panel-body no-padding text-align-center">
|
||||
<include href="templates/modules/requirements_table.html"/>
|
||||
</div>
|
||||
<div class="panel-footer text-align-center">
|
||||
<check if="{{ !@tplCounter('get') }}">
|
||||
<true>
|
||||
<h3 class="panel-title txt-color txt-color-success">OK</h3>
|
||||
</true>
|
||||
<false>
|
||||
<h3 class="panel-title txt-color txt-color-warning">{{ @tplCounter('get') }} Warnings</h3>
|
||||
</false>
|
||||
</check>
|
||||
</div>
|
||||
</div>
|
||||
{{ @tplCounter('reset') }}
|
||||
</check>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -204,7 +226,7 @@
|
||||
|
||||
<div class="panel panel-default pricing-big">
|
||||
<div class="panel-heading text-left">
|
||||
<h3 class="panel-title">PHP configuration</h3>
|
||||
<h3 class="panel-title">PHP config (php.ini)</h3>
|
||||
</div>
|
||||
<div class="panel-body no-padding text-align-center">
|
||||
<include href="templates/modules/requirements_table.html"/>
|
||||
@@ -222,13 +244,13 @@
|
||||
</div>
|
||||
{{ @tplCounter('reset') }}
|
||||
|
||||
{* System Env requirements *}
|
||||
<check if="{{ @checkSystemConfig }}">
|
||||
<set requirementsData="{{ @checkSystemConfig }}" />
|
||||
{* Redis requirements *}
|
||||
<check if="{{ @checkRedisConfig }}">
|
||||
<set requirementsData="{{ @checkRedisConfig }}" />
|
||||
|
||||
<div class="panel panel-default pricing-big">
|
||||
<div class="panel-heading text-left">
|
||||
<h3 class="panel-title">Environment variables [optional]</h3>
|
||||
<h3 class="panel-title">Redis configuration [optional]</h3>
|
||||
</div>
|
||||
<div class="panel-body no-padding text-align-center">
|
||||
<include href="templates/modules/requirements_table.html"/>
|
||||
@@ -970,10 +992,10 @@
|
||||
<kbd class="pull-right">
|
||||
<check if="{{ @cacheSize.all }}">
|
||||
<true>
|
||||
{{ @cacheSize.all }}
|
||||
{{ @cacheSize.all }}
|
||||
</true>
|
||||
<false>
|
||||
0 KB
|
||||
0KB
|
||||
</false>
|
||||
</check>
|
||||
</kbd>
|
||||
@@ -981,7 +1003,7 @@
|
||||
</div>
|
||||
|
||||
<div class="panel-body no-padding">
|
||||
<check if="{{ @cacheType() == 'redis' }}">
|
||||
<check if="{{ @cacheType === 'redis' }}">
|
||||
<div class="btn-group btn-group-justified">
|
||||
<span class="btn btn-default disabled btn-fake">
|
||||
Redis cache
|
||||
@@ -1001,7 +1023,7 @@
|
||||
{{ @cacheSize.data }}
|
||||
</true>
|
||||
<false>
|
||||
0 KB
|
||||
0KB
|
||||
</false>
|
||||
</check>
|
||||
</kbd>
|
||||
@@ -1020,7 +1042,7 @@
|
||||
{{ @cacheSize.template }}
|
||||
</true>
|
||||
<false>
|
||||
0 KB
|
||||
0KB
|
||||
</false>
|
||||
</check>
|
||||
</kbd>
|
||||
|
||||
Reference in New Issue
Block a user