четверг, 9 октября 2014 г.

Планировщик задач в мудле

Когда я в очередной раз установил, мудл, то обратил внимание на файл readme.txt, где содержались "рекомендации" по установке. Читаем
4) Set up a cron task to call the file admin/cron.php
   every five minutes or so.
Я знал, что cron - это планировщик задач в nix-овых системах. И что на него вешают все работы, которые должны выполняться периодически. Не думал, что в мудле есть такие. Кстати, возможность пользовательского доступа к планировщику задач - проверка качества хостинга. Далеко не все хостеры дают такую возможность.
Итак, надо в cron запускать скрипт admin/cron.php. Понятно, что его надо запускать через интерпретатор php. Служба тех.поддержки сказала, что запускать через строку
php - f путь доступа/cron.php
Хостер даже предоставляет интерфейс (есть такая функция crontab) для формирования заданий. Результат должен приходить мне на email.
Продуем. Вставляем в планировщик строчку
php -f /home/cp526266/public_html/moodle/admin/cron.php
В ответ получаем сообщение.
Web cron can not be executed as CLI script any more, please use admin/cli/cron.php instead
Оказывается, что CLI - Command Line Usage (Использование из командной строки) - специальный тип скриптов, который используется для системных задач. Немного гуглим. Как я понял CLI скрипты должны располагаться в специальной директории. Смотрим. Правильно, есть в мудле директория admin/cli. Меняем строку запуска в планировщике
php -f /home/cp526266/public_html/moodle/admin/cli/cron.php
Приходит сообщение
!!! <p>Error: Database connection failed</p><p>It is possible that the database is overloaded or otherwise not running properly.</p><p>The site administrator should also check that the database details have been correctly specified in config.php</p> !!!
 Не цепляет базу данных. Придется лазить по тексту. Залезаем в cron.php, видим строчку
require(dirname(dirname(dirname(__FILE__))).'/config.php');
Чтобы понять, что произошло, посмотрим описание функции dirname. "dirname — Возвращает имя родительского каталога из указанного пути". Авторы программы рассчитывали на то, что путь до родительского каталога будет состоять из трех уровней. Вроде правильно. Смотрим файл error_log.txt. Нам сообщают
09-Oct-2014 06:25:02 Europe/Moscow] PHP Warning:  mysqli::mysqli(): (HY000/2002): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) in /home/cp526266/public_html/moodle/lib/dml/mysqli_native_moodle_database.php on line 376
Ищем инфу по ошибке HY000/2002. Оказывается проблема в том, что MySQL не может соединиться с текущей базой потому, что занят сокет для сеанса. (Насколько я помню протокол TCP/IP для создания сеанса связи нужно устойчивое соединение - сокет). В доках рекомендуется либо очищать существующий сокет, либо создавать новый. Вообще написано, что MeSQL может работать либо через порт, либо через сокет. Через сокет создается безопасное соединение.
Смотрим программу mysqli_native_moodle_database.php. Строка 376
$this->mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname, $dbport, $dbsocket);
Похоже. Откуда берется переменная dbsoket? Чуть выше находим строчки
// dbsocket is used ONLY if host is NULL or 'localhost',
// you can not disable it because it is always tried if dbhost is 'localhost'
if (!empty($this->dboptions['dbsocket'])
and (strpos($this->dboptions['dbsocket'], '/') !== false or strpos($this->dboptions['dbsocket'], '\\') !== false)) {
                       $dbsocket = $this->dboptions['dbsocket'];
            } else {
                       $dbsocket = ini_get('mysqli.default_socket');
}
Из которых следует, что в случае, если при название сервера первоначальное - "localhost", и название сокета пустое, то будет работать одна ветка оператора (которая работает сейчас), в противном случае другая. При том, что менять код очень бы не хотелось. Во-первых, судя по названию скрипт mysqli_native_moodle_database.php - основной драйвер базы данных, поэтому чревато. Во-вторых, это не системно: потом забудешь, никакие автоматические изменения использовать нельзя и пр. Надо придумать способ, как решить проблему, не меняя кода.
Другой вариант - переназвать  либо сервер, либо сокет. Вообще-то это делает при инсталляции мудла, но ведь в нашем распоряжении есть настроечный файл config.php. Изменяем название сокета. Не проканало. Увы.

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

Вечером читаю еще раз документацию. Оказывается есть версия для веб-запуска. В каталоге moodle/admin (Именно ее я пытался запустить через интерпретатор php в начале). Пробуем запустить скрипт через браузер. Как ни удивительно - Работает!!!

НО, я не могу повесить это задание на планировщик, потому, для автоматического режима надо скрипт гонять через интерпретатор php, см. начало и все повторится снова. Пока пусть так будет. Потом еще поразбираюсь.

Лицензия Creative Commons
Произведение «Блог "Эффективное дистанционное образование"» созданное автором по имени А.Н.Гущин, публикуется на условиях лицензии Creative Commons «Attribution» («Атрибуция») 3.0 Непортированная.
Основано на произведении с an1954.blogspot.ru. на следующий (также выделен полужирным шрифтом):