Как можно управлять запущенной функцией и данными в ней?
Всем привет!
Подскажите, как можно осуществить управление запущенной функции? То есть приостановить выполнение или удалить вовсе выполнение.
Есть функция, которая берет данные из таблицы и проверяет их. Эта функция вызывается через крон, если пользователь выставил проверку в настройках.
Но как сделать управление c уже запущенными данными не совсем понятно. Например необходимо приостановить проверку данных из таблицы прямо сейчас, у тех записей, в которых присутствует значение 1 в колонке pause.
Как вклиниться в процесс запущенный через крон и управлять данными, вот вопрос. Возможно надо делать какой-то слушатель, который бы постоянно слушал определенные настройки, что-то запутался...
vadikrudnov, ну еще раз задача не понятна - но вполне возможно что достаточно проверять при выполнении проверки - изменился ли статус у данных, если нет - не проверять. или после проверки - если статус изменился - не вносить изменения.
Дмитрий, Задача: управление проверкой данных пользователем. В таблицу поступают данные по АПИ. Все проверки должны быть в списке задач, которыми можно управлять. Данных на проверке может быть больше миллиона. Пользователь должен вручную запускать проверку на основе фильтров по записям в таблице, и также чтобы у него была возможность приостанавливать проверку, удалять данную задачу.
vadikrudnov,
1. ну решение в лоб простое - у вас должна быть таблица задач, где лежат поставленные задачи пользователями с фильтрами, и при обработке этой задачи эпизодически опрашивать изменилась ли запись с задачей. правда решать такое через крон, такое себе - может лучше очереди?
2. ну можно полезть в какой нибудь swoole, roadrunner или еще чего и мутить там - но мне кажется вы не сможете.
но вполне возможно что достаточно проверять при выполнении проверки - изменился ли статус у данных, если нет - не проверять. или после проверки - если статус изменился - не вносить изменения.
Пришли новые данные с неизвестными значениями, надо запустить проверку этих данных с помощью фильтров, категорий, распределений и т.д.
Берется список данных и через foreach прогоняется, если на каждой записи делать запрос в базу с проверкой, выставил ли пользователь настройку или нет, то это очень много запросов получится)
vadikrudnov, если вы видете что данные изменились - вы тупо сворачиваете работу, следующий крон или следующая попытка обработки - начнет сначала. можно дергать не каждую обработку - а каждую десятую.
ну если не устраивает - говорю идете в swoole или еще чего, и пишете свой манагер процессов. ну или - бросаете пхп и идете в язык который более подходит к таким задачам. но я бы искренне порекомендовал первый вариант
Дмитрий, очереди хорошая идея, но не видел там, возможности приостановки выполнения и удаления очереди. Очередь нужна, когда уже все жестко известно и надо выполнять без остановки.
vadikrudnov, очереди выигрывают у крона здесь только более гибкой настройкой количества одновременных обработок.
Если вам нужно прямое управление процессами - нужен манагер процессов. А куда идти за ним - я уже сказал.
В вашем случае приостановка задачи должна решаться через что то - базу данных, какую нибудь ключ-значение, или еще чего, что он должен мониторить что бы получить сообщение о том что ему надо сдохнуть.
Ну еще как вариант - это прикапывать к каждой задачи getmypid и банальным kill'ом сносить
Дмитрий, попробовал тут Getmypid получать в очередях, так там получается один и тот же pid для всех запущенных очередей с задачами. Поэтому если грохнуть очередь с одним pid, то грохнуться все, а это плохо.
vadikrudnov, не мудрено. потому что у вас joba будет выполнятся в рамках процесса воркера. И таким макаром джобу вам нихрена не прибить - только воркера.
Самый простой вариант сделать подобное управление в php — использовать внешние флаги. Вариантов много, например, можно взять Redis или Memcache: один процесс (управляющий) ставит флаг cron:check:row123:pause = 1, второй процесс (обрабатывающий) в своём цикле считывает флаг. Аналогично можно сделать флаг cron:check:stop = 1 и остановить обработку вообще.
К внешним флагам должен быть постоянный доступ из запущенной задачи, а это означает постоянное дергание базы с запросом. В задаче может обрабатываться больше миллиона записей, это означает что на каждой записи будет идти запрос в базу, что не есть хорошо.
vadikrudnov, поэтому и "базу" я предложил in-memory: Redis и Memcache. Они прекрасно справляются с обработкой десятков тысяч запросов в секунду. Тем более, что здесь наипростейший read-write со сложностью O(1).