несколько миллионов таймеров? Допустим я "запустил стройку" или "посадил морковку" и мне говорят что через 7 минут будет готово. И таких таймеров в игре почти по количеству "площади" (сотни), а в пределах многопользовательского режима - миллионы... обычный setTimeout вроде не разумно уже использовать! B через setInterval не разумно раз в секунду "долбить" миллионЫ элементов в SQL запросе.
в целом на джаваскрипте делать такое не разумно, думай в этом направлении
Один таймер раз в секунду проверяет что произошло нового
С каких пор JS перестал быть "полноценным языком"? Вопрос лишь в алгоритмах...
я где-то сказал что JS перестал быть "полноценным языком"?
Хочу хоть какую-нибудь оптимизацию! Пока смотрю в сторону "закешировать ближайшую" и ждать только один таймаут, а потом искать следующую ближайшую.
А как еще можно понять "в целом на джаваскрипте делать такое не разумно, думай в этом направлении"? Значит "есть языки получше"? Те на которых это можно сделать в отличии от JS? JS экранирован от "нативных команд ОС/оборудования" (в отличии от Си, ассемблера и возможно "компилируемых" типа паскаля, го), но это единственный "недостаток". Для 10М таймеров не нужен "прямой доступ к процессору", Вопрос лишь в алгоритмах... К тому-же не уверен что ВСЕ онлайн стратегии сделаны не на Ноде!
если ты не можешь понять как сделать нормально и хочешь на сервере запустить миллионы таймеров на джаваскрипте, то "в целом на джаваскрипте делать такое не разумно"
можешь заюзать условный priority queue по времени (вставка нового action будет стоить log n соотв), раз в n времени (секунда, полсекунды, 100 мс..) забирать из priority queue элементы, у которых endTime >= currentTime, они всегда будут первыми в такой очереди
А на чем тогда?????
на бумажке, настолку лучше сделай, а потом наберешься опыта, переосмыслишь свой подход и тогда уже сделаешь нормально
Примерно так и думал сделать... Вопрос скорее - как у ДРУГИХ это сделано? Это уже должно быть неким "патерном" со времен древних стратегических игр с сотнями юнитов, да еще и в онлайне...
Не говорите глупости! Мне ПАТЕРН нужен, а не "настолку на бумажке". Я не игру пишу, а онлайн сервис (да хотя-бы телеграмм-бот) где у каждого пользователя может быть от одного до... (понятия не имею, но до 50 точно) таймеров, которые должны сделать "пуш". И не знаю сколько десятков-сотен-тысяч пользователей может быть в системе. ПОКА что обычный таймаут справляется на одном ядре в ноде. Но не хочу чтобы сервак ТОЛЬКО "за будильником следил".
по сути так у других и реализовано, как же иначе? почекай ещё hashed wheel timers, может тебе такое решение больше подойдёт
а то решение через priority queue, которое я сразу предложил, я сейчас вспомнил, называется calendar queue можешь ещё про soft heap почитать
Спасибо! Не знал что гуглить...
и в принципе почитай про то, как работать с discrete-event simulation, я уверен, что найдёшь какие-то работы и видео на эту тему, с конференций точно должно что-то быть
Ух, "загрузили"... Я думал простенький патерн, а там... )))
Вполне разумно. Одно из первых игр такого типа в ВК делали как раз на ноде, ещё и версии 0.х
миллионы сетинтервалов?
если игрушка нагружена, как писал тот кому я ответил, то мне кажется не очень разумно
Ты подумай о том, что будешь делать, если процесс упал/нода переехала, и все твои таймеры пропали Очевидно же что таймер не нужен
да и хуево сделана
Нет конечно
А мне кажется для игр такого плана нода может быть оптимальным выбором. Вряд ли там есть cpu intensive
Понятно что данные на 99% лежат в базе... Вопрос был как их оттуда вытягивать и обрабатывать - логично что не по таймеру для каждой 10М задач, и не ежесекундным опросом базы. Я в принципе уже сделал, но на всякий случай сюда спросил чтобы на "велосипедность" проверить - вдруг есть решение более логичное/простое. Или наоборот более сложное но надежное. Сейчас при запуске ищу в базе "ближайшую", и настраиваю таймаут на это событие. После срабатывания - настраиваю на следующее. Там есть нюанс с колбэками и долгой обработкой одного события, но в принципе все работает. Отладку проводил в браузере - выяснил одну пакость JS - если страница уходит в "не активную закладку", то браузер может ЗАДЕРЖИВАТЬ таймаут! (не "останавливает", а именно "задерживает") Причем СИЛЬНО! Учился на малых таймаутах в пределах 5-15 сек и получал "задержку" таймаута до 3х минут! Сейчас пишу "обнадеживатель" таймаута... Поэтому и возник вопрос по "игровым таймерам" - там обычно не бывает таких багов.
Так в ноде тоже нет никакой гарантии, что таймер отстрелит вовремя. Он не должен отстрелить ранее указанного таймаута, а вот задержка может быть любой
Не "любой"! Если разброс в 10 раз на секундах, то на "часах" может оказаться в несколько СУТОК! А "критично" уже больше 10 минут... Поэтому продумываю "дублирующие" таймеры, которые "погрешность" попытаются исправить...
Яннп, но всё же любой. Потому что ты можешь банально синхронной операцией заблочить ивент луп на год, и таймер, установленный на две секунды, у тебя сработает только через год А идея с таймерами, которые дублируют другие таймеры и правят погрешности, это просто 🔥, да. Потом понадобятся таймеры, которые корректируют корректирующие таймеры, и таймеры, которые корректируют корректирующие корректирующие таймеры 👍👍👍
https://developer.chrome.com/blog/timer-throttling-in-chrome-88/
В ноде (насколько понял) не принято блочить ивент-луп тяжелыми задачами! Но вот ОС может решить выделить слишком мало ресурсов Ноде и та "заснет". Это правда лишь предположение... Но в БРАУЗЕРЕ может происходить что угодно! Я пишу механизм который будет работать с большим кво таймеров и на Ноде, и в Браузере и в NWjs и даже (в идеале) в андроиде(который любит поспать). Если у меня ОДИН таймаут "до ближайшей", который может "прыгать" от 0.1 сек до 70 часов... Почему-бы не запустить еще 1-2 которые раз в 5 минут (или в 1/3 таймаута) будут проверять "не отстает ли таймаут"
не принято - не значит что ты 100% не будешь его блочить если ты сделаешь второй таймер чтоб тот следил за первым, то как ты будешь проверять что первый затормозил если второй затормизит тоже когда ты залочишь луп?
второй надо пускать в воркер треде просто) и из него мессаги слать первому)
ну, вот он запустит второй таймер в другом треде, а в основном будет работать по первому таймеру и ждать событие из второго на проверку и тут бац, основной тред залочится, событие отловится только через секунду (или час), кому верить?
а потом вынести это в два микросервиса. Первый коронный - второй контрольный
Нужно отправлять синхронизирующее событие по какому-нибудь вебсокету, если есть уверенность, что браузер сам троттлит таймеры
Представь что ты "первому" таймеру дал задачу разбудить тебя когда на часах будет 7 утра. "Первый таймер" завел старый механический будильник, который может отставать. На всякий случай "второй таймер" должен по тому-же будильнику проснуться через 3 часа и проверить время - если его разбудили не через 3.01, а через 4-5 часов - значит первому надо ввести "поправку" и перевести будильник так чтобы сработать ДО того как ты "опаздаешь на работу" ))) Я не "таймерный маньяк"! ))) Просто сильно взбесило что в браузере настроил выводить в консоль каждые 10-30 секунд и обнаружил что он "так и быть" выводит туда каждые 3-5 минут... А если бы это был таймер на нечто ВАЖНОЕ?
https://t.me/nodejs_ru/1142527
если в момент х всё залочится на основном треде то уже ничего не спасёт
а если он сожрет память или залочит процесс в браузере? браузер встанет пока не разберется с текущими задачками и отработает по события только через время
ну и ну, вот это вывод, а гражданин f все еще хочет юзать таймеры
а ты в курсе как евент луп работает? nodejsный а не браузерный
Я хочу снизить риск не от СВОИХ багов в коде, а баги ОС (или браузера). Залочить тред - это "мои кривые руки". Но если я завел будильник на хостинге, а он в это время решил запустить фоновую задачку и таймеры начали СИЛЬНО отставать...
А есть разница?
остается только пожелать тебе удачи выкладывай код на гитхаб, будет интересно похуисосить посмотреть твою реализацию
Не принято не значит, что синхронных операций вообще нет. У тебя время таймера может сработать тогда, когда el занят обработкой запроса, в котором надо сделать json parse для сложной структуры, а потом ещё reduce для результата - и никакой точности таймера не будет
Там слишком сильно "интегрированный в проект" код для гитхаба. Сейчас переделываю свой домашний NWjs сокет-сервер чтобы он нотифы выдавал при входящих отправляемых таймером. "независимый" тестер, которым можно будет праверить если в РАЗНЫХ браузерах и в ноде будут сильные погрешности со временем на больших интервалах (в часах). Проект не "горящий" - недельку буду приглядывать и делать выводы...
Мне можно верить
Фиксить баги ос нодой это сильно
Я же говорил - мне не критичны "миллисекунды" (или даже минута, на тяжелый процесс в евентлупе), но если таймер отстанет на пару часов... При том что браузер или ОС просто решили "сберечь заряд аккумулятора" или "нагрев процессора"... Я провожу разработку/отладку на секундах-минутах. А работать оно должно на часах или даже сутках. Как-то не правильно будет обнаружить такой баг уже на релизе!
Ну это вряд ли коммерческий или ценный проект, много не потеряешь если выложишь его в гитхаб
Конечно коммерческий! Только "без дедлайна". И модуль "интеграцией" идет. Правда пока в "не активном" режиме - рабочие выходы на внешние тестеры и в консоль. пускаю.
тогда передаю лучи поддержки твоему тим лиду и тех диру
Тогда по прежнему актуален вопрос с рестартом процесса Плюс таймауты могут накапливать отставание, если у тебя логика построена на их перезапуске Возможно таймауты для такой задачи плохое решение. Не зря тут уже час бурлит
Есть "системное время" от которого задаются таймауты и идет "математика расчетов". А есть "следующее срабатывание", которое выполняется на колбэк таймаута или тайминтервала. Хранение "времени следующего срабатывания" в базе или в таблице памяти. Если "математику расчетов" разбудят СЛИШКОМ поздно, то будет критично... Это всетаки таймеры для сотрудников на производстве, а не "игрушка".
Именно когда вкладка не активна, а когда переключаетесь на вкладку, то таймеры нормально работают таймеры?
Обсуждают сегодня