Здравствуйте. Есть проект на laravel, php. Фреймворк предлагает систему очередей с откладыванием на время.
Стоит задача отложить выполнение Job на 30 секунд с максимальной погрешностью в 500мс (лучше - меньше). Пишу на винде (к сожалению), посему нету возможности проверить beanstalkd или redis, как обработчики очередей, в нормальных условиях.
На винде редис выдает погрешность 2+ секунды, что не лезет вообще ни в какие ворота. Изменится ли ситуация на linux сервере? Если нет, то изменится ли ситуация при использовании beanstalkd на linux?
Если и это нет, то прошу подсказать способ сделать точный timeout на php (вход на php и выход на php, а что за кадром - не важно. хоть js).
Вы задачу опишите, похоже что вы что-то не так спроектировали, или мыслите слишком прямолинейно, находя решения "в лоб", там где есть более простые пути.
Ну я описал задачу. На счет проектирования - все нормально. Это realtime проект с визуальным таймером на клаентсайде, а значит бекенд тоже должен быть точным, что-бы успеть за 200-300мс сработать, отправить левый http запрос на кое-какой сервис, получить инфу и отдать ее клиентам.
В конечном итоге пользователь увидит таймер, по истечению которог увидет результат. Результат должен быть именно в конце, в начале не получится.
на счет простых путей: подскажите, пожалуйста. Я всегда пытаюсь найти решение сам, но на php ничего подобного не видел и не нашел. На js я бы сделал это с помощью nanotimer, но пишу на php (и рад этому).
я так понимаю задача - отдать клиенту контент не раньше чем через х секунд, а не получить контент у себя через х секунд? В таком случае не проще иметь контент заранее, но запросы которые приходят раньше от клиента просто отфутболивать? Пришел запрос - смотрим время - рано, если еще много секунд - пишем пользователю что он лох и не на тех нарвался, если осталось мало секунд - слип пару сек и отдать что надо.
Alex Wells: мм, форекс, бинарные опционы, все дела....
имхо - один демон, имеющий список клиентских соединений, и время когда отдать значение, прокручивает список себе потихоньку, по наступлении времени отдает последнее имеющееся в базе значение и удаляет клиента из очереди, походу еще проверяя какую-то переменную на наличие свежих покойничков клиентов. И второй, который каждую секунду снимает в базу данные с удаленного сервера, иначе вы замудохаетесь для каждого клиента проверять состояние отдельно. Все будет работать именно в тот момент когда нужно, без всяких задержек, расхождений и проч.
ThunderCat: Нет, отношения к бирже не имеет даже косвенного))
На счет двух демонов.. зачем?? У меня стоит SocketCluster. Всем сокетам нужно отправить идентичную инфу, в один и тот-же момент. Это уже реализовано и работает идеально, хоть с сотней тысяч клиентов =)
Я мог-бы сделать кучу кода на nodejs возле сокет-сервера, но я принципиально не хочу этого делать. Бизнес логика в php. Уж лучше usleep)
Так что никаких демонов, никаких баз. Асинхронный таймер на x секунд, выполняющий php скрипт через указанное время с точностью в 500мс. Другие варианты не катят.
Все больше склоняюсь к "в лоб", ибо пока это единственный вариант. Все-же лучше, чем код на js.
Alex Wells: Сделайте демона на Nodejs, который для логики на php будет что то вроде сервиса(службы-таймера). Php может подписаться на уведомление скажем через 30 сек. Node js через 30 сек вызовет php. В логике php на вход можно сделать что то вроде события. Или можно такого демона-таймер на php написать.
Если вы сделаете sleep на 30 сек на php, весь процесс вместе с занятой памятью повиснет у вас, а если таких процессов будет много?
yurygolikov: sleep я имел ввиду в отдельном процессе. К примеру, нужное время - 30 секунд, а поставить таймер на 20 (в очереди laravel) и еще 10 дождатся usleep'ом.
На счет nodejs - думаю проще будет на php. Плюс задержки php -> nodejs -> php -> nodejs, как-то не очень)
По сути очередь это тоже такие же задержки.
+ вы не правильно написали задержка будет только в момент запуска nodejs демоном по событию времени - php. Она не будет больше 500мс. Если беспокоитесь можно за секунду запустить, а далее на php usleep эту секунду.
yurygolikov: Если запускать его каждый раз при надобности - вообще получается глупость. Если просто висящий демон всегда - слишком много js кода.
В любом случае, получится точно тоже самое. Единственная разница - очереди в laravel уже написаны, готовы, работают. А демона еще прийдется писать, но толку то не будет.
Я не вникал, как работают очереди в фреймворке, посему ответить не могу, как и что запускает процесс. Но главное, что оно работает, причем из коробки.
Задавая этот вопрос, я надеялся услышать что-то более радужное чем куча демонов или sleep)
Задавая этот вопрос, я надеялся услышать что-то более радужное чем куча демонов или sleep)
Учитывая специфику работы пхп скриптов, было бы странно услышать что либо по типу "да, чувак, в пхп есть такая клевая штука которая отслеживает и синхронизирует время на клиенте и сервере, висит в памяти, места не занимает, проц не жрет, и делает как раз то что тебе надо!". Нет, нифига, пых задуман с циклом запустил-отработал-умер, и исходя из этого ему нужен ВНЕШНИЙ источник раздражения, который разбудит Герцена скрипт и желательно еще и параметры передаст. Ну и демоны как раз по этой части как бэ.
Может хватит уже это повторять? Да, он так был задуман и так и работал в 1995. Но с тех пор много воды утекло и на ветке 5.х вполне возможно написать нормального демона который будет работать сколько угодно без утечек памяти и прочих неприятностей. И это даже не особо сложно, да и гайдов полно.
Может хватит уже это повторять? Да, он так был задуман и так и работал в 1995.
Ничего кардинально не поменялось. Да, работать стало лучше, и т.д., но рабочий цикл с тех пор не поменялся для 98% задач под пых, для циклических демонов есть более подходящие инструменты.