Main

Основной цикл системы

В этой заметке я опишу, как функционирует система с точки зрения задач, выполняемых периодически.

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

Пару слов о том, почему эти сущности называются циклами. Всё просто -- они собой представляют запущенные бесконечные циклы, каждый из которых периодически инициирует то или иное событие, в зависимости от того, для чего этот цикл был запущен. Почему их несколько? Просто потому, что это позволяет паралельно и независимо друг от друга обеспечивать запуск тех или иных процедур.

Итак, циклы должны запускаться вместе со стартом системы и не закрываться в процессе работы. Инициируются циклы запуском скрипта ./cycle.php. Что делает этот скрипт -- он смотрит в папке ./scripts/ все файлы с именем cycle_*.php и создаёт паралельные процессы на запуск каждого из этих "дочерних" скриптов. Соответственно, каждый cycle-скрипт самостоятельно определяет, какие именно действия он должен производить.

На данный момент имеются вот такие основные циклы (их количество может меняться в зависимости от конфигурации системы):

  • cycle_main.php -- самый базовый цикл системы, обновляет системное время, а так же отвечает за работу объектов класса Timer
  • cycle_scheduler.php -- отвечает за выполнение задач, запланированных с помощью функций setTimeOut, AddScheduledJob и им подобных
  • cycle_execs.php -- цикл, отвечающий за запуск команд, добавленных через функцию safe_exec
  • cycle_webvars.php -- цикл, обеспечивающий обновление веб-переменных
  • cycle_bluetooth.php -- цикл сканера bluetooth-устройств
  • cycle_onewire.php , cycle_onewire_starred.php -- циклы опроса 1-wire сети
  • cycle_ping.php -- цикл опроса устройств online
  • cycle_rss.php -- цикл обновления RSS-потоков
  • cycle_skype.php (windows), cycle_X101_skype.php (linux) -- цикл/демон скайп-бота
  • cycle_snmp.php -- цикл опроса SNMP-устройств
  • cycle_states.php -- цикл обновления статусов состояния системы
  • cycle_watchfolders.php -- цикл сканирования изменений папок
  • cycle_zwave.php -- цикл опроса Z-Wave устройств

Рассмотрим, что представляет собой cycle-скрипт на примере цикла ./scripts/cycle_webvars.php.

chdir(dirname(__FILE__) . '/../'); //переходим на папку уровнем выше (для сохранения путей к библиотекам)

include_once("./config.php");
include_once("./lib/loader.php");
include_once("./lib/threads.php");

set_time_limit(0); // нужно обязательно для того, чтобы система не закрыла скрипт по тайм-ауту

// соединяемся с базой данных
$db = new mysql(DB_HOST, '', DB_USER, DB_PASSWORD, DB_NAME); 

// загружаем настройки
include_once("./load_settings.php");
include_once(DIR_MODULES . "control_modules/control_modules.class.php");

$ctl = new control_modules();

// подключаем модуль веб-переменных
include_once(DIR_MODULES . 'webvars/webvars.class.php');
$webvars = new webvars();

while(1)  // начало бесконечного цикла
{
  //выводим информацию о том, что цикл работает (без этого бывало, что система закрывала процесс из-за неактивности)
   echo date("H:i:s") . " running " . basename(__FILE__) . "\n";
  // на всякий случай каждый час пишем в лог, что цикл работает -- можно убрать
   if (!$updated_time || (time() - $updated_time) > 1 * 60 * 60) 
   {
      //Log activity every hour
      DebMes("Cycle running OK: ".basename(__FILE__));
      $updated_time=time();
   }
  // устанавливаем переменную времени последнего прохождения цикла -- полезно для слежения за тем, работает ли цикл
   setGlobal((str_replace('.php', '', basename(__FILE__))).'Run', time());

   // далее, непосредственно действие, которое нужно вызывать периодически
  // в данном случае, это запуск процедуры обновления веб переменных 
  // (какие именно переменные нужно обновлять это уже забота модуля -- наша задача каждую секунду запускать метод проверки)
   $webvars->checkAllVars(); 

  // если появляется в корневой папке файл ./reboot, то выходим из цикла -- система закрывает процесс
  // когда все процессы, инициированные скриптом ./cycle.php будут закрыты, то и сам скрипт закроется
   if (file_exists('./reboot')) 
   {
      $db->Disconnect();
      exit;
   }
   sleep(1); // пауза в 1 секунду, чтобы не перегружать процессор
}
 
 

Обсуждение

 

sergejey: Обсуждение страницы Основной цикл системы

martynovis: Добрый день. столкнулся со следующей непонятностью. Не могу определить почему возникает вот такое явление. после запуска все хорошо в течении минут 2-3 а потом вот это:

ksgroup: Добрый день. столкнулся со следующей непонятностью. Не могу определить почему возникает вот такое явление. после запуска все хорошо в течении минут 2-3 а потом вот это: Очень подозреваю что это связано с настройкой PHP. Где то в php.ini есть настройка времени "жизни" запущенного скрипта. В вашем случае скорее всего максимальное время "жизни" скрипта эти самые 2-3 минуты. Нужно установить бесконечное время. К сожалению точно не помню какой именно параметр нужно изменить. Поищите по форуму - вроде бы было уже что то такое. Ну или спросите гугл о настройках PHP. Хотя возможно я и ошибаюсь. Возможно где то еще собака зарыта.

Amarok: _majordomo\server\php\php.ini переменная max_execution_time

martynovis: _majordomo\server\php\php.ini переменная max_execution_time Выключаю сервер Меняю значение (0 и 180 да и вообще любое) При запуске параметр сбрасывается в 60

Amarok: _majordomo\server\php\php.ini переменная max_execution_time Выключаю сервер Меняю значение (0 и 180 да и вообще любое) При запуске параметр сбрасывается в 60 И правда...

martynovis: _majordomo\server\php\php.ini переменная max_execution_time Выключаю сервер Меняю значение (0 и 180 да и вообще любое) При запуске параметр сбрасывается в 60 Поменял через .htaccess проблема осталась((

sergejey: php.ini надо менять в этом файле C:\_majordomo\server\config_tpl\php.ini и потом перезапускать систему. но думаю что проблема не в этом, а в каком-то из заданий, которое запускается по таймеру. очень вероятно, что ошибка в части кода, по выполнении которого "крашится" весь цикл.

martynovis: php.ini надо менять в этом файле C:\_majordomo\server\config_tpl\php.ini и потом перезапускать систему. но думаю что проблема не в этом, а в каком-то из заданий, которое запускается по таймеру. очень вероятно, что ошибка в части кода, по выполнении которого "крашится" весь цикл. Проблема в том что туда ни чего не добавлял. у меня от стандарта отличие только в добавлении торентов + подключение ардуины (ардуина отсылает данные через POST) и настройка GPS Tracker.

Panchez: У меня тоже самое, после обновления дней 10 назад.

sergejey: Хм... очень странно. Только этот цикл останавливается? и в Debmes никаких ошибок связанных с базой данных? Буду разбираться...

denis: Хм... очень странно. Только этот цикл останавливается? и в Debmes никаких ошибок связанных с базой данных? Буду разбираться... Вроде это обсудили в теме 'ошибка в common.class.PHP" это собственно и есть причина остановки цикла.

sergejey: Ах, вот оно что... В общем, исправил в исходниках.

nick7zmail: Добрый день всем) Такой вопрос (точнее даже два) 1) все ли то что выводится в историю, произносится голосовым сервисом? (на этот вопрос вроде где то видел ответ - да, но все же) 2) Система каждый час произносит текущее время...это можно как нибудь отключить?

ErmolenkoM: все ли то что выводится в историю, произносится голосовым сервисом? вывод в историю идет командой http://smartliving.ru/Main/ProgrammingFunctions say($ph,$level) -- говорит фразу (использует глобальные переменные $voicemode [именно говорить] и $commandLine [преобразует ответ в echo utf2win(), иначе просто echo]). $level указывает уровень важности фразы (в зависимости от текущих настроек минимального уровня произношения, фраза может быть либо озвучена голосом либо просто записана в историю сообщений). Соответственно либо выводится, либо - нет. Система каждый час произносит текущее время...это можно как нибудь отключить? Панель управления / Объекты / Timer.OnNewMinut $h=(int)date('G',time()); $m=date('i',time()); if (($h>=8)) { if ($m=="00") { say(timeNow()); } } Вот этот код и произносит. Соответственно - убрать.

nick7zmail: Благодарю! Исчерпывающий ответ

[ Обсудить на форуме ]

 

MajorDomo

Информация

Проекты

Партнёры

edit SideBar

 
 
 

 

Blix theme adapted by David Gilbert, powered by PmWiki