Перезапуск скрипта процессора из админки автоматически

Здравствуйте.

Разрабатываю дополнение по импорту большого кол-ва товаров в минишоп2. Импорт запускается из админки. За импорт отвечает файл процессора synch.class.php.

Столкнулся с проблемой времени выполнения скрипта. Нужно грузить картинки со стороннего сайта, а это по примерным подсчётам на первый импорт всех товаров уйдёт около 2 часа работы. Ясное дело, что php не позволит так долго работать скрипту из браузера. Через консоль сервера запускать скрипт не получится, т.к. клиенту этого не объяснишь.

Думаю может получится как-то организовать автоматический перезапуск скрипта процессора с того места, на котором остановился, через, например, 20-50 товаров, либо через 20 секунд работы скрипта.

В связи с этим вопрос разработчикам дополнений: возможно ли отправлять в админку из процессора такой запрос, который автоматически в админке будет обрабатываться и перезапускать скрипт с нужного места, на котором остановились?

Решение под катом



Решение было найдено на гитхабе Василия, за что ему (и конечно Володе за помощь) — огромное СПАСИБО!

github.com/bezumkin/mSearch2/blob/master/core/components/msearch2/processors/mgr/index/create.class.php#L85
github.com/bezumkin/mSearch2/blob/master/assets/components/msearch2/js/mgr/widgets/index.form.js#L44
Павел Гвоздь
06 июня 2015, 14:08
modx.pro
2
2 119
+1
Поблагодарить автора Отправить деньги

Комментарии: 19

Павел Гвоздь
06 июня 2015, 17:13
0
Уточню один момент:
У нас в админке список файлов для импорта, мы кликнув на одном из них попадаем во всплывающее окно с указанием параметров выгрузки. Указываем параметры, жмём кнопку, данные передаются в процессор synch — импорт начался. Дойдя до определённой точки скрипт импорта отправляет данные обратно в админку, в админке этот ответ обрабатывается, если параметр «success» — 0, а «continue» — 1, то снова отправляем в скрипт процессора запрос с параметром «step» — 2, который означает, что импорт нужно продолжить.
    Павел Гвоздь
    06 июня 2015, 17:16
    0
    Если есть какие-то примеры, которые могли бы помочь в реализации задуманного — скиньте, пожалуйста. Я буду очень признателен за помощь.
        Павел Гвоздь
        06 июня 2015, 17:31
        0
        Огромное спасибо, дружище! Именно то, что мне жизненно необходимо!
          Альберт
          06 марта 2020, 02:15
          0
          Я что-то затупил на таком же моменте ) Не помните, как реализовали в итоге?
            Павел Гвоздь
            06 марта 2020, 07:49
            0
            На стороне PHP делаешь N итераций, следя при этом, чтобы время выполнения скрипта не выходило за пределы 50-70% от max_execution_time и отсылаешь флаг done = true/false, в зависимости от того, надо ли продолжать итерации или скрипт полностью отработал. На стороне JS смотришь флажок done и шлёшь обратно в PHP, если ещё не закончил.
            Да, костыль, однако другого не придумать на связке PHP + JS.
              Николай Савин
              06 марта 2020, 08:42
              0
              А через sleep() разве нельзя такое сделать без js?
                Павел Гвоздь
                06 марта 2020, 08:48
                0
                Раскрой своё решение. Я не понимаю, о каких таких слип ты говоришь.
                  Николай Савин
                  06 марта 2020, 08:57
                  0
                  Я говорю о PHP функции sleep, которая останавливает работу скрипта на указанное время, и, насколько я понимаю (я могу ошибаться), предотвращает наступление max_execution_time.
                  По крайней мере я пользовался примером Николая-философа и это помогало делать пошаговую разбивку чтения больших данных.
                    Сергей Шлоков
                    06 марта 2020, 09:02
                    +1
                    sleep() там только для того, чтобы видеть, что пишется в логе. Иначе будет сразу done. У Николая ровно такая же связка php+js.
                      Павел Гвоздь
                      06 марта 2020, 09:03
                      +1
                      1) Sleep ничего не останавливает. Она задерживает, откладывает, ставит на паузу. Не останавливает!

                      2) Что-то я впервые такую фигню слышу, что sleep предотвращает max_execution_time.

                      3) В коде на сайте Ильи примерно то же, о чём я говорил. Просто реализовано непосредственно в компоненте Console и запускается через флажок completed установленный в сессию в $_SESSION['Console'].
                    Сергей Шлоков
                    06 марта 2020, 09:15
                    0
                    Моё решение без js. Правда ни разу не пробовал ))

                    П.С. Самому интересно стало. Надо будет попробовать.
                      Павел Гвоздь
                      06 марта 2020, 09:24
                      0
                      Так у тебя в решении ты не контролируешь возвращаемые данные. А у меня суть вопроса 2015 года ?именно в том, чтобы контролировать процесс выполнения.
                        Сергей Шлоков
                        06 марта 2020, 09:29
                        0
                        Контролировать можно через лог. Попробую на выходных.
                          Андрей Степаненко
                          10 марта 2020, 22:03
                          0
                          Да, через лог можно контролировать, чтением каждую секунду сообщений.

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

                          Получаем 30 записей отправляем их на exec_bg_script.
                          Ждем пока у этих 30 записей поставиться метка: завершено.
                          После чего получаем следующие 30 и продолжаем дальше.
                          Пока из обработки не уйдут все записи во временной таблице.

                          Так всегда можно отследить когда был запуск и завершение.

                          В общем нужна очередь, и какой то цикл который будет перезапускать всю эту процедуру.
                          Сергей Шлоков
                          07 марта 2020, 10:19
                          +3
                          Потестил. Создание 1000 ресурсов через обычный newObject() занимает 10 секунд. А через exec_bg_script() — 1 секунду. Использовал 10 параллельных потоков. Если интересно, могу запилить видос.
                            Андрей Степаненко
                            10 марта 2020, 21:34
                            0
                            А как контролировать?
                            Понятно что на 1000 ресурсов можно использовать. А если обновляется 100к ресурсов, Получается ответ не получен!
                            Очередь таких заданий забьет память и процессор.
                            Просто думаю как это встроить к примеру в msPre так как достаточно долго обновляется даже те же 2000 ресурсов при объеме в 100к.
                            Точней даже понимаю что это работать будет только, в безконтрольном режиме. И это проблема.
                            Андрей Степаненко
                            10 марта 2020, 21:43
                            0
                            Если отключить сессии и не дожидаться ответа, то получится аналогичный функционал:
                            Через ajax посылать все запросы разом к примеру в 1000 запросов, и не ждать ответа. Что то типо через цикл запустить.
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            19