В таких случаях у меня есть простой и одновременно полезный совет: запустите этот код в дебаггере, останавливайтесь в каждой строчке и смотрите значения переменных.
Кстати, скрипт не оптимален, цикл должен начинаться не м нуля, а с единицы, потому что нулевой элемент мы уже взяли, и если начинаем с нуля, то сравниваем нулевой элемент с самим собой на первом шаге
Ankhena
1. Если label у чекбокса виден, текст контрастен и легко читается, и на него можно навести фокус, то проблем с доступностью не будет.
2. Если правильно стилизовать label, так, чтобы сразу было понятно, нажата кнопка (переключатель) или нет, то и у зрячих людей проблем не будет.
Т.е. вам, фактически нужен переключатель, а не кнопка?
Логика действия кнопки: нажал - она зажата, отпустил - она отжалась.
Логика действия переключателя: нажал один раз - вкл, нажал второй раз - выкл.
Так?
Такого не знаю.
Но ведь можно сделать более адекватно. Смотрите, Firebase ведь в конечном итоге хранилище данных. Т.е. вам нужно н в основную программу вытащить данные из Firebase по какому-то критерию. И положить точно так же.
Так вот, на первом этапе примените паттерн Repository и вытащите всё, что касается работы с данными в функции этих репозиториев.
Эту работу можно делать частями, даже не прерывая внедрение других фичей.
Когда всё, что связано с данными окажется внутри репозиториев, а остальной код будет доставать данные только из репозиториев, тогда уже наступит второй этап, на котором переписать код для другой базы внутри этих репозиториев будет очень легко.
Василий Дёмин,
Самое нормальное решение.
Многие при переходе с динамических языков пытаются неосознанно притащить в язык со статической типизацией весь мусор оттуда, накопленный за много лет опыта.
Плюс к этому Go не просто язык со статической типизацией, а язык, который всеми своими фибрами будет сопротивляться подобным практикам, неоправданно усложняющим код и делающим его трудно читаемым и трудно отлаживаемым.
Fcorpion Rub-zero, Рекомендация: сначала делаете проект, он приносит деньги. А когда он вдруг начинает подтормаживать или сильно кушать ресурсы, вот тогда и наступает тот самый момент, когда надо начинать задумываться об экономии на спичках.
Чтобы этот момент определить, сразу интрегрируйте мониторинг, например prometheus
Fcorpion Rub-zero, Не совсем понял вопрос. Я передаю не файл, а указатель на файл. Просто код создания файла я вынес в отдельную функцию getFileWriter, чтобы не захламлять код. Эта функция возвращает в основную функцию SetupLogger нужный нам поток логгирования (указатель на файл) и функцию закрытия. А в main мы возвращаем только функцию закрытия файла для defer.
Если в коде какие-то проблемы, то я там некоторые вещи на скорую руку вырезал, потому что у меня там ещё и кастомная обёртка для логов использовалась, так что мог что-то повредить)
Ипатьев, Этот "клубок зависимостей" не так уж страшен, как его малюют)
И простая инициализация всего по порядку гораздо проще в плане отладки, чем дебажить самописный DI контейнер.
А ежели не хочется всё инициализировать при каждом запросе, то тут без кодогенерации либо какого-то там RoadRunner не обойдешься. Тогда уж проще фреймворк взять...
Если менеджер, на которого повесили головную боль по доработке или починке сайта всегда сможет с вами связаться и в разумные сроки получить решение, то вероятность того, что он постоянно будет с вами работать и посоветует вас по сарафанному радио всем своим знакомым, весьма велика. Они очень любят специалистов, которые избавляют их от головной боли. Самое интересное в этом, что так можно внезапно получить очень крупный заказ.
Но стоит один раз подвести и заставить его искать вам замену, то эта сарафанная ветка может навсегда умереть.
Причем, даже если вы не обладаете знаниями по решению какой-то конкретной проблемы, то станьте посредником, найдите человека, который сможет это решить под вашим началом
tmgrr, Тут всё зависит от того, что вы делаете в обработчике.
Если, например, запросы во внешние API не требуют очередности, а требует очередности только обработка их конечного результата после этих запросов, то можно добавить конкурентности...
В этой же таблице с данными можно добавить поле result, в которое складывать данные от внешних запросов. Тогда можно будет запустить много обработчиков параллельно.
И уже напоследок ввести ещё один обработчик, который будет только единственным, и который будет из этой таблицы выбирать самую старую запись, смотреть, есть ли данные в поле result.
Если данные есть, то обработать и пометить запись окончательно обработанной или удалить её. А если данных в поле result нет, то ждать пока они там не появятся.
Таким образом мы ускорим общую работу всей обработки в целом, т.к. самые долгие операции - это вызовы внешних API, и именно их мы будем обрабатывать параллельно, а готовый результат будет обрабатываться строго по очереди
Rsa97, Я просто не специалист в Laravel, больше по Symfony. Поэтому и описал универсальную идею, используя базу данных как очередь, потому что с базой данных даже начинающие умеют работать.
В Symfony есть компонент Messenger, который всё это берет на себя, умеет делать очереди как из базы данных, так и в брокерах.
Наверняка, в Laravel есть подобный инструмент
BjornBorn, Для понимания SQL ему нужны драйвера. Он сам их установит. Phpstorm очень хорошо умеет работать с базой данных. У него отличный инструмент есть для этого "Database tool window"
Установите этот плагин, если он ещё не установлен, и подключите свою базу туда. Вы сможете прямо оттуда даже редактировать данные, писать запросы в специальной консоли и т.д. и т.п.
View | Tool windows | Database
И тогда Phpstorm будет вам давать подсказки прямо в коде программы. Он покажет, если вы ошиблись с названием таблицы или поля и т.д.
Если на локалке и на проде по-разному жрёт память, то проблема, скорей всего, в вашем коде. Ведь базы данных, наверняка разные, и обрабатываете вы разные объемы данных. И если вы в каком-то цикле маленькими кусочками обрабатываете большие данные, временные переменные в которых содержат большие куски данных, то сборщик мусора может не успевать очищать память. Она лавинообразно накапливается и вылетает.
evomed, Идея вставки тудущек в методы, имплементирующие интерфейс - это очень здравая идея. Видимо, поэтому разрабы даже не подумали делать опцию по их отключению.
Подумайте, как мы добавляем методы в класс. У нас появляется идея о том, что в классе нам нужен новый метод с конкретным функционалом. И мы его берём и сразу добавляем. Это наше решение.
А как мы чаще всего имплементируем методы интерфейса? Нам нужно, чтобы наш класс соответствовал какому-то чужому интерфейсу, чтобы мы имели возможность использовать наш класс где-то в других местах в каком-то контексте. Т.е. нас форсят это делать. И если интерфейс километровый, мы пишем эти методы, тихо проклиная создателя этой библиотеки или фреймворка. А нам не нравится, когда нас форсят, и некоторые методы так и могут остаться пустыми, потому что вот конкретно сейчас у нас нет времени на них. И это потом может внезапно бабахнуть.
Будь моя воля, я бы, вообще, там вместо тудущек писал die("not implemented"), чтобы точно не забыть
Кстати, скрипт не оптимален, цикл должен начинаться не м нуля, а с единицы, потому что нулевой элемент мы уже взяли, и если начинаем с нуля, то сравниваем нулевой элемент с самим собой на первом шаге