Xor

 
<<< Назад

Переезд на мастер спустя год

заметки для памяти

Поставил мастер спустя год. Вношу правки свои. Предупреждаю, система на Вин10, база на рам-диске, ПУ нет.
Апач, mySQL, VLC - всё работает службами (ну, и редис службой - он у меня остался в одном месте из-за железа)
Связь с внешним миром - через Телеграм и Connect. Стоит УПС. Минут 40 он держит МДМ с роутерами, потом штатно гасит всё.

Из-за этого нюансы (всё равно, бд в памяти) - отказался от редиса как кэша, все таблицы мемори перевел в майисам -- это расширило возможности кэша, поле DATAVALUE в таблице cached_values сделал varchar(2048)

Соответственно, в \lib\caching.class.php замена
255 на 2048

function saveToCache($key, $value)
{

    if (is_array($value) || strlen($value) > 2048) {
        return;
    }

Циклы

Общее замечание - считаю, что хранить время обновления циклов и их контроль в свойствах - излишне. До обновления на мастер отлично работало в кэше только, без заведения свойств. План на будущее - сделать и тут так же.

Циклы привел к общему формату - использование переменной имени

$cycleVarName = 'ThisComputer.'.str_replace('.php', '', basename(__FILE__)).'Run';
setGlobal($cycleVarName, time(), 1);

проверка что работает

while (1) {
    if (time() - $checked_time > 20) {
        $checked_time = time();
        setGlobal($cycleVarName, $checked_time, 1);
    }
...

схема цикла в общем случае:

//настройки цикла
...
$checked_time = 0;

$cycleVarName = 'ThisComputer.'.str_replace('.php', '', basename(__FILE__)).'Run';
setGlobal($cycleVarName, time(), 1);
echo date("H:i:s") . " running " . basename(__FILE__) . PHP_EOL;

while (1)
{
   if (time() - $checked_time > 20)
   {
      $checked_time = time();
      setGlobal($cycleVarName, $checked_time, 1); //отметим, что цикл живой

   }
...
//тело цикла
...
   if (isRebootRequired() || IsSet($_GET['onetime'])) //выход из цикла
   {
      exit;
   }
   sleep(1);
}

DebMes("Unexpected close of cycle: " . basename(__FILE__));

\scripts\cycle_phistory.php:
что сделано - замечено, что для отображения переполнения очереди истории используется свойство phistory_queue_problem, которое каждую секунду опрашивается.
Исправил так, с сохранением вывода ошибки переполнения

...
$limit = (int)gg('phistory_queue_limit');
if (!$limit) {
  $limit = 200;
}
$limit_plus = $limit +1; //добавлено для определения выхода за лимит
...
$queue_error_status = 0; //введем переменную статуса ошибки
while (1) {
    if (time() - $checked_time > 20) {
        $checked_time = time();
        setGlobal($cycleVarName, $checked_time, 1);
    }

    //$queue_error_status = gg('phistory_queue_problem');

    //$tmp = SQLSelectOne("SELECT COUNT(*) as TOTAL FROM phistory_queue;");
    //$count_queue = (int)$tmp['TOTAL'];

    $queue = SQLSelect("SELECT * FROM phistory_queue ORDER BY ID LIMIT ". $limit_plus);
    if ($queue[0]['ID']) {

        $total = count($queue);
        if($total > $limit && !$queue_error_status){
                //sg('phistory_queue_problem',1);
                        $queue_error_status = 1;
                $txt = 'Properties history queue is too long ('.$total.')';
                echo date("H:i:s") . " " . $txt . "\n";
                registerError('phistory_queue',$txt);
        } elseif ($total <= $limit && $queue_error_status) {
            //sg('phistory_queue_problem',0);
                  $queue_error_status = 0;
        }

\scripts\cycle_main.php:
Тут рассуждения такие - тут каждую 20 (после исправления, в исходнике - каждую 5) секунду в цикле пишется в свойства ThisComputer.uptime общее время работы и в ThisComputer.uptimeText форматированное время работы с точностью до минуты). Оба эти свойства зависят только от ThisComputer.started_time и текущего времени. Заполнение их я из цикла выкинул и добавил в скрипт, который вызывается раз в минуту

while (1) {
    if (time() - $checked_time > 20) {
        $checked_time = time();
        setGlobal($cycleVarName, $checked_time, 1);

        //$timestamp = time() - $started_time;
        //setGlobal('ThisComputer.uptime', $timestamp);
/*
        $years = floor($timestamp / 31536000);
        $days = floor(($timestamp - ($years * 31536000)) / 86400);
        $hours = floor(($timestamp - ($years * 31536000 + $days * 86400)) / 3600);
        $minutes = floor(($timestamp - ($years * 31536000 + $days * 86400 + $hours * 3600)) / 60);
        $timestring = '';
        if ($years > 0) {
            $timestring .= $years . 'y ';
        }
        if ($days > 0) {
            $timestring .= $days . 'd ';
        }
        if ($hours > 0) {
            $timestring .= $hours . 'h ';
        }
        if ($minutes > 0) {
            $timestring .= $minutes . 'm ';
        }
        setGlobal('ThisComputer.uptimeText', trim($timestring));
*/
    }
        ...

скрипт:

$started_time = getGlobal('ThisComputer.started_time');
$timestamp = time() - $started_time;
//setGlobal('ThisComputer.uptime', $timestamp);
saveToCache('MJD:ThisComputer.UPTIME', $timestamp); //сохраняем только в кэш, потому что это нафиг не надо хранить в базе

        $years = floor($timestamp / 31536000);
        $days = floor(($timestamp - ($years*31536000)) / 86400);
        $hours = floor(($timestamp - ($years*31536000 + $days*86400)) / 3600);
        $minutes = floor(($timestamp - ($years*31536000 + $days*86400 + $hours*3600)) / 60);
        $timestring = '';
        if ($years > 0){
            $timestring .= $years . 'г ';  //заодно, на русский переведем
        }
        if ($days > 0) {
            $timestring .= $days . 'д ';
        }
        if ($hours > 0) {
            $timestring .= $hours . 'ч ';
        }
        if ($minutes > 0) {
            $timestring .= $minutes . 'м ';
        }
        //setGlobal('ThisComputer.uptimeText', trim($timestring));
        saveToCache('MJD:ThisComputer.uptimeText', trim($timestring));//сохраняем только в кэш, потому что это нафиг не надо хранить в базе
        postToWebSocketQueue('ThisComputer.uptimeText',trim($timestring)); //отошлём в интерфейс

Цикл cycle.php

Вот эту часть, где, как я понимаю, ищем циклы с непустым Контрол и останавливаем или перезапускаем

 ...
        $qry = "OBJECT_ID=" . $thisComputerObject->id . " AND (TITLE LIKE 'cycle%Run' OR TITLE LIKE 'cycle%Control')";
        $cycles = SQLSelect("SELECT properties.* FROM properties WHERE $qry ORDER BY TITLE");

        $total = count($cycles);
        $seen = array();
        for ($i = 0; $i < $total; $i++) {
                $title = $cycles[$i]['TITLE'];
                $title = preg_replace('/Run$/', '', $title);
                $title = preg_replace('/Control$/', '', $title);
                if (isset($seen[$title])) {
                        continue;
                }
                $seen[$title] = 1;
                $control = getGlobal($title . 'Control');
                if ($control != '') {
                        DebMes("Got control command '$control' for " . $title, 'threads');
                        if ($control == 'stop') {
                                $to_stop[$title] = time();
                        } elseif ($control == 'restart' || $control == 'start') {
                                $to_stop[$title] = time();
                                $to_start[$title] = time() + 30;
                        }
                        setGlobal($title . 'Control', '');
                }

        }
        ...

переписал на:

...
        //не получить ли просто список циклов с непустым Контрол?
        $qry = "SELECT REPLACE(REPLACE( KEYWORD, 'Control', '' ),'MJD:ThisComputer.','') TITLE,DATAVALUE control FROM `cached_values` WHERE `KEYWORD` like 'MJD:ThisComputer.cycle%Control' and DATAVALUE>''";  // fix 2021-04-20
        $cycles = SQLSelect($qry);
        $total = count($cycles);
      for ($i = 0; $i < $total; $i++) {
         $title = $cycles[$i]['TITLE']; //возьмём титле
         $control = $cycles[$i]['control'];//команда

            DebMes("Got control command '$control' for ".$title,'threads');
            if ($control == 'stop') {
               $to_stop[$title] = time(); 
            } elseif ($control == 'restart' || $control == 'start') {
               $to_stop[$title] = time(); 
               $to_start[$title] = time() + 30; 
            }
            setGlobal('ThisComputer.'.$title.'Control','');
      }
...

Цикл веб-сокетов:
upd 06/09/2021
в файле цикла

$cycleNameWS = 'ThisComputer.'.str_replace('.php', '', basename(__FILE__)).'Run';
//setGlobal($cycleName, time(), 1);
saveToCache('MJD:'.$cycleNameWS,time());

В файле MajordomoApplication.php

        global $cycleNameWS;
        if ($cycleNameWS) {
            $checked_time = time();
            //setGlobal($cycleName, $checked_time, 1);
            saveToCache('MJD:'.$cycleNameWS, $checked_time);

$cycleName заменил на $cycleNameWS чтобы не перепутать + переход на кэш

Код

избавляемся в мастере от чересчур частой чистки
в common.class.php функция runScheduledJobs() приводим к такому виду первые строки:

if (date('s')=="10")  {
SQLExec("DELETE FROM jobs WHERE EXPIRE <= '" . date('Y-m-d H:i:s') . "'");
}
$sqlQuery = "SELECT *
                            FROM jobs
                         WHERE PROCESSED = 0
                             AND EXPIRED   = 0
                             AND RUNTIME   <= '" . date('Y-m-d H:i:s') . "' AND EXPIRE > '" . date('Y-m-d H:i:s') . "'";

\load_settings.php:

$offset = timezone_offset_get(new DateTimeZone(SETTINGS_SITE_TIMEZONE), new DateTime());
$offset_text = timezone_offset_string($offset);
//SQLExec("SET time_zone = '" . $offset_text . "';"); // избавляемся от частых запросов

\lib\mysqli.class.php:

         $this->latestTransaction=time();
         //$this->Exec("set NAMES 'utf8', CHARACTER SET 'utf8', character_set_client='utf8', character_set_results='utf8', collation_connection='utf8_general_ci';");// избавляемся от частых запросов
         return 1;

Старое моё - исправлен формат даты в Панели управл...

Модули

Optimizer

будет дополняться...

Обсуждение (3) (7)

Смотрите так же:
12.02.2024 Китайская панель в подрозетник с экраном 480*480
29.10.2023 MQTT в МДМ - способ обработки топика через метод
03.04.2023 Todoer: обмен данными с Яндекс календарём
31.03.2023 Todoer: календарь на год
30.03.2023 Todoer: анонс + программное создание задачи
08.05.2022 Глобальный поиск - добавление своих сущностей. Upd Внедрено
05.01.2022 Яндекс Лампочка в Yandex Devices - добавление сцен
24.03.2021 Ещё о старте/остановке МДМ в Винде
18.02.2021 Модуль Todoer
06.01.2021 Для виндузятников - перенос бд на рам-диск
22.11.2020 Календарь-планировщик
01.08.2020 Irbis как терминал
18.05.2020 Китайская камера rtsp + vlc как перекодировщик для html
12.05.2020 Опыт интеграции МДМ с Я.Алисой ещё одним способом - без белого адреса, москита, ПУ.(дополнено)
07.05.2020 Поправим формат даты в Панели управления
11.04.2020 Баловство с шаблонами
26.03.2020 Простые правила - вариант модуля. ч. 2
25.03.2020 Простые правила - вариант модуля
20.12.2019 расширение средств работы с events updated
20.11.2019 По следам наших выступлений - сколько мы наэкономили?
04.11.2019 Группа как объект - экономим на коде - 2
26.10.2019 Прикручиваем Grafana к Мажордому
11.10.2019 Группа как объект - экономим на коде
25.09.2019 Если у вас нет телеги...
11.09.2019 Датчик присутствия из ип камеры
30.07.2019 Win-платформа-замена ffmpeg для получения скриншотов из rstp - потока
24.06.2019 Форматированный отчет в телеграм - имитация таблицы
30.04.2019 Используем зомбо-ящик в Мажордомо
24.03.2019 О среднем в Мажордомо
31.10.2018 Об "обделённых" пользователях Win-систем -- с точки зрения кэширования winTTS сообщений
16.09.2018 Перезагрузка Мажордомо в Win-системах

Домодедово, Россия

На форуме: xor