Палантир. Часть 21. Боты, рефакторинг.
#палантир@eshu_coding
Идея с Final State Machine оказалась удачной, но первая реализация естественно вышла комом. Как только появилось понимание архитектуры, которую я хочу видеть в ботах, я сел и провел глобальный рефакторинг, оставив только логику и некоторые удачные модули, а заодно сменил базу, с которой работают боты, на MongoDB. У них в нынешнем виде вся логика работы с базой сводится к двум операциям: вставить/прочитать информацию по известному id.
Выбор базы обусловлен следующими причинами:
1. Операции без сложной логики "вставить/прочитать" в ней работают ощутимо быстрее, чем в постгресе.
2. У монги достаточно агрессивный механизм кеширования, который удобен для логики работы бота: Монга как хомяк набивает оперативку "горячей" информацией до тех пор, пока не выйдет за установленный лимит или не съест всю память. Информации там не будет очень много (перерасход 1-2 Гб оперативки я даже не замечу), а вот дополнительная скорость доступа к данным о юзерах, активных в настоящий момент не повредит.
В целом, MongoDB мне понравилась, с третьего подхода. Теперь хотя бы понятно, где она в тему, и в чём лучше PostgreSQL: скорость работы на некоторых операциях и простота использования.
При этом, главная её особенность, я бы сказал киллер-фича - простота построения распределенного хранилища, которое просто расширять и администрировать, мной пока не используется.
#палантир@eshu_coding
Идея с Final State Machine оказалась удачной, но первая реализация естественно вышла комом. Как только появилось понимание архитектуры, которую я хочу видеть в ботах, я сел и провел глобальный рефакторинг, оставив только логику и некоторые удачные модули, а заодно сменил базу, с которой работают боты, на MongoDB. У них в нынешнем виде вся логика работы с базой сводится к двум операциям: вставить/прочитать информацию по известному id.
Выбор базы обусловлен следующими причинами:
1. Операции без сложной логики "вставить/прочитать" в ней работают ощутимо быстрее, чем в постгресе.
2. У монги достаточно агрессивный механизм кеширования, который удобен для логики работы бота: Монга как хомяк набивает оперативку "горячей" информацией до тех пор, пока не выйдет за установленный лимит или не съест всю память. Информации там не будет очень много (перерасход 1-2 Гб оперативки я даже не замечу), а вот дополнительная скорость доступа к данным о юзерах, активных в настоящий момент не повредит.
В целом, MongoDB мне понравилась, с третьего подхода. Теперь хотя бы понятно, где она в тему, и в чём лучше PostgreSQL: скорость работы на некоторых операциях и простота использования.
При этом, главная её особенность, я бы сказал киллер-фича - простота построения распределенного хранилища, которое просто расширять и администрировать, мной пока не используется.
Telegram
Эшу быдлокодит
Прошу прощения за долгое молчание, было безумно много работы.
Работа над диссертацией продолжается, но пока вяленько, планирую активизироваться на следующей неделе.
За прошедший месяц я реализовал и запустил новый проект: парсер текстов из телеграма, …
Работа над диссертацией продолжается, но пока вяленько, планирую активизироваться на следующей неделе.
За прошедший месяц я реализовал и запустил новый проект: парсер текстов из телеграма, …
Палантир. Часть 22. Бот-агрегатор.
#палантир@eshu_coding
Ранее я описывал механизм работы "оповещалки" о происходящем в телеграме по ключевым словам: мной пишется запрос для полнотекстового поиска, который через каскад триггеров вызывает функцию pg_notify и сообщает внешним сервисам, что искомая фраза найдена.
Изначально этот функционал крутился в основной базе, на которой и так складирование всей информации и обслуживание поисковика. Чтобы разгрузить базу, я использовал следующий трюк: самодельную подписку на gRPC. Все желающие сообщений могут постучаться с запросом на сервер, после чего между ними и сервером повиснет gRPC канал, через который master-сервер потоком сливает все сообщения, только что пришедшие от сборщиков данных.
А на другом конце провода - практически полный клон master сервера, я его назвал NotificationProvider, с практически идентичной базой, в которой и происходит анализ. Но оповещение вылетает не в бота на прямую, а публикуется в брокер сообщений RabbitMQ, к которому уже цепляются боты - подписчики. RabbitMQ, NotificationProvider и PostgreSQL запущены с помощью Docker-compose и работают как единый организм.
Такой подход позволяет плодить ботов-агрегаторов в неограниченных количествах, хотя сейчас их всего 6 штук.
#палантир@eshu_coding
Ранее я описывал механизм работы "оповещалки" о происходящем в телеграме по ключевым словам: мной пишется запрос для полнотекстового поиска, который через каскад триггеров вызывает функцию pg_notify и сообщает внешним сервисам, что искомая фраза найдена.
Изначально этот функционал крутился в основной базе, на которой и так складирование всей информации и обслуживание поисковика. Чтобы разгрузить базу, я использовал следующий трюк: самодельную подписку на gRPC. Все желающие сообщений могут постучаться с запросом на сервер, после чего между ними и сервером повиснет gRPC канал, через который master-сервер потоком сливает все сообщения, только что пришедшие от сборщиков данных.
А на другом конце провода - практически полный клон master сервера, я его назвал NotificationProvider, с практически идентичной базой, в которой и происходит анализ. Но оповещение вылетает не в бота на прямую, а публикуется в брокер сообщений RabbitMQ, к которому уже цепляются боты - подписчики. RabbitMQ, NotificationProvider и PostgreSQL запущены с помощью Docker-compose и работают как единый организм.
Такой подход позволяет плодить ботов-агрегаторов в неограниченных количествах, хотя сейчас их всего 6 штук.
Telegram
Эшу быдлокодит
Прошу прощения за долгое молчание, было безумно много работы.
Работа над диссертацией продолжается, но пока вяленько, планирую активизироваться на следующей неделе.
За прошедший месяц я реализовал и запустил новый проект: парсер текстов из телеграма, …
Работа над диссертацией продолжается, но пока вяленько, планирую активизироваться на следующей неделе.
За прошедший месяц я реализовал и запустил новый проект: парсер текстов из телеграма, …
Палантир. Часть 23. Логика команд сервисам.
#палантир@eshu_coding
Как и обещал в конце поста, я таки переделал логику работы приказов для сборщиков.
Телеграм имеет следующую особенность: простой доступ к данным (по id, без суточных лимитов) возможен только когда аккаунт "знаком" с запрашиваемым объектом. Хэш "знакомства" хранится в базе сессии. Про найденное решение для хранения сессий я тоже писал ранее.
Для максимально оперативной подгрузки обновлений чатов и каналов нужно, чтобы каждый из сборщиков имел в сессии записи о максимально возможном числе каналов и чатов, тогда работа по выгрузке будет распределена равномерно.
Кроме того, сборщики периодически приходят в негодность (баны, взломы, повреждение сессии), что также обуславливает необходимость отдельного "культивирования" подробной сессии. Для этих целей примерно 50% от суточного лимита в 200 тяжелых запросов идет к уже известным каналам, а еще 50 - тратятся на расширение охвата. И всё это приправлено костылями для максимального размытия пика нагрузок во времени.
Теперь, когда сборщик стучится за приказом, с вероятностью около 5% ему выдаётся запрос с суточным лимитом, а дальше с вероятностью 50 на 50 он запрашивает GetFullChannel или на новый канал или на уже известный. В итоге, когда очередной сборщик отваливается, отряд не замечает потерю бойца, а мониторинг некоторых каналов и чатов осуществляется буквально в реальном времени.
#палантир@eshu_coding
Как и обещал в конце поста, я таки переделал логику работы приказов для сборщиков.
Телеграм имеет следующую особенность: простой доступ к данным (по id, без суточных лимитов) возможен только когда аккаунт "знаком" с запрашиваемым объектом. Хэш "знакомства" хранится в базе сессии. Про найденное решение для хранения сессий я тоже писал ранее.
Для максимально оперативной подгрузки обновлений чатов и каналов нужно, чтобы каждый из сборщиков имел в сессии записи о максимально возможном числе каналов и чатов, тогда работа по выгрузке будет распределена равномерно.
Кроме того, сборщики периодически приходят в негодность (баны, взломы, повреждение сессии), что также обуславливает необходимость отдельного "культивирования" подробной сессии. Для этих целей примерно 50% от суточного лимита в 200 тяжелых запросов идет к уже известным каналам, а еще 50 - тратятся на расширение охвата. И всё это приправлено костылями для максимального размытия пика нагрузок во времени.
Теперь, когда сборщик стучится за приказом, с вероятностью около 5% ему выдаётся запрос с суточным лимитом, а дальше с вероятностью 50 на 50 он запрашивает GetFullChannel или на новый канал или на уже известный. В итоге, когда очередной сборщик отваливается, отряд не замечает потерю бойца, а мониторинг некоторых каналов и чатов осуществляется буквально в реальном времени.
Telegram
Эшу быдлокодит
Прошу прощения за долгое молчание, было безумно много работы.
Работа над диссертацией продолжается, но пока вяленько, планирую активизироваться на следующей неделе.
За прошедший месяц я реализовал и запустил новый проект: парсер текстов из телеграма, …
Работа над диссертацией продолжается, но пока вяленько, планирую активизироваться на следующей неделе.
За прошедший месяц я реализовал и запустил новый проект: парсер текстов из телеграма, …
Палантир. Часть 24. Итоги, общая архитектура проекта.
#палантир@eshu_coding
По завершении ботов-агрегаторов проект я считаю завершенным, время описать что же получилось и подвести итоги.
На картинке:
DataFair - мастер сервер
DataLoader - сборщик
Пунтиром обведен docker-compose, в котором живет Observer - анализатор входящих данных в реальном времени.
SearchBot - поисковик @palantir_search_bot
ObserverBot - нижеперечисленные боты-агрегаторы:
@space_observer_bot
@gas_news_bot
@poland_belaruss_migr_bot
@investment_trends_bot
@Biden_smm_assistant_bot
Цветом выделены те сервисы, число которых может быть любым или близко к этому.
Итого, за время работы над проектом, начиная с 1 марта 2021 изучено:
1. Немного администрирования Linux
2. Docker, Docker-compose
3. CD/CI Github Actions
4. gRPC
5. PostgreSQL во всех позах
6. RabbitMQ
7. MongoDB
8. Подход к построению приложений Dependency Injection
9. Телеграмная кухня, обладающая своей спецификой
10. Полнотекстовый поиск
#палантир@eshu_coding
По завершении ботов-агрегаторов проект я считаю завершенным, время описать что же получилось и подвести итоги.
На картинке:
DataFair - мастер сервер
DataLoader - сборщик
Пунтиром обведен docker-compose, в котором живет Observer - анализатор входящих данных в реальном времени.
SearchBot - поисковик @palantir_search_bot
ObserverBot - нижеперечисленные боты-агрегаторы:
@space_observer_bot
@gas_news_bot
@poland_belaruss_migr_bot
@investment_trends_bot
@Biden_smm_assistant_bot
Цветом выделены те сервисы, число которых может быть любым или близко к этому.
Итого, за время работы над проектом, начиная с 1 марта 2021 изучено:
1. Немного администрирования Linux
2. Docker, Docker-compose
3. CD/CI Github Actions
4. gRPC
5. PostgreSQL во всех позах
6. RabbitMQ
7. MongoDB
8. Подход к построению приложений Dependency Injection
9. Телеграмная кухня, обладающая своей спецификой
10. Полнотекстовый поиск
Произошло моё первое практическое знакомство с оптимизацией запросов. Нормально пользоваться планом я пока не научился, но первый медленный запрос к базе успешно оптимизирован.
Делал я полнотекстовый поиск в базе проекта #палантир@eshu_coding, приправленный дополнительным параметром: id юзера или канала, по которому осуществляется поиск. Эти поля у меня проиндексированы индексом hash, потому выборка записей по конкретным значениям этих полей мгновенная. Полнотекстовый поиск же штука относительно медленная.
Запрос вида
где @@ , грубо говоря, оператор соответствия текста запросу, на всей базе выполняется секунд 20.
Судя по всему, Postgres проверяет все записи на соответствие запросу, а затем уже применяет фильтр по id.
Для ускорения запроса мне на помощь пришли Common Table Expressions (CTE). Суть их - в поэтапном выполнении сложного запроса. Если переписать запрос с использованием CTE, скорость выполнения становится стабильно около 300 мс.
Переписанный запрос:
#кодинг
#postgresql
Делал я полнотекстовый поиск в базе проекта #палантир@eshu_coding, приправленный дополнительным параметром: id юзера или канала, по которому осуществляется поиск. Эти поля у меня проиндексированы индексом hash, потому выборка записей по конкретным значениям этих полей мгновенная. Полнотекстовый поиск же штука относительно медленная.
Запрос вида
select * from messages where full_text_req @@ post_text and chat_id = id;
где @@ , грубо говоря, оператор соответствия текста запросу, на всей базе выполняется секунд 20.
Судя по всему, Postgres проверяет все записи на соответствие запросу, а затем уже применяет фильтр по id.
Для ускорения запроса мне на помощь пришли Common Table Expressions (CTE). Суть их - в поэтапном выполнении сложного запроса. Если переписать запрос с использованием CTE, скорость выполнения становится стабильно около 300 мс.
Переписанный запрос:
with sel as (select * from messages where chat_id = id) select * from sel where text @@ full_text_request;
#кодинг
#postgresql
🔥1
Продолжу затронутую уважаемым @ssleg тему тестов. Я наконец повзрослел и осознал логику организации функциональных и интеграционных тестов.
Если коротко - используем CD/CI (в моем случае Github Actions) для прогона обычных unit-тестов, завязанных на внешние сервисы. Нужные элементы - базы данных/другие микросервисы - поднимаем на отдельном сервере с помощью Docker из того же скрипта CD/CI. По завершении тестов - убираемся за собой.
Для иллюстрации создал репозиторий на гитхабе и настроил конвейер CD/CI.
Суть происходящего: проверяется взаимодействие самописного сервиса на c#, MongoDB и Tarantool-а. В моём случае - на идентичность тестовых данных, положенных в обе базы из моего сервиса.
Скрипт CD/CI состоит из трех частей (job-ов):
1. Развертывание инфраструктуры (deploy_infrastructure). Я тупо клонирую на сервер репозиторий и поднимаю прямо в папке решения всю систему с помощью
2. Собственно тестирование (build_and_run_test). Если инфраструктура была развёрнута - запускаются все тесты, реализованные в соответствующих проектах, в т.ч. завязанные на базы данных.
У меня реализовано несколько тестов, проверяющих работоспособность тестовой среды и один "содержательный" тест.
При воспроизведении тесты живут в чем-то вроде виртуалки, предоставляемой Github-ом. Известны параметры подключения к сервисам, запущенным на предыдущей стадии, потому с ними можно провзаимодействовать и провалидировать результат.
Если всё ок - job загорается зелёным, нет - красным. К результату можно привязывать различные действия: пропускать коммит в репозиторий, начинать деплой в прод и т.д.
3. Зачистка следов (clear_infrastructure). Вне зависимости от результатов прошлой стадии, останавливаются и удаляются все запущенные на этапе 1 сервисы.
Имея простенький сервер-полигон за 130р/месяц и бесплатный Github actions можно реализовать практически любые свои фантазии по покрытию кода тестами: у меня тестируется только класс для работы с базами.
P.S. Синтаксис в скрипте вида
#кодинг
#автотесты
#devops
Если коротко - используем CD/CI (в моем случае Github Actions) для прогона обычных unit-тестов, завязанных на внешние сервисы. Нужные элементы - базы данных/другие микросервисы - поднимаем на отдельном сервере с помощью Docker из того же скрипта CD/CI. По завершении тестов - убираемся за собой.
Для иллюстрации создал репозиторий на гитхабе и настроил конвейер CD/CI.
Суть происходящего: проверяется взаимодействие самописного сервиса на c#, MongoDB и Tarantool-а. В моём случае - на идентичность тестовых данных, положенных в обе базы из моего сервиса.
Скрипт CD/CI состоит из трех частей (job-ов):
1. Развертывание инфраструктуры (deploy_infrastructure). Я тупо клонирую на сервер репозиторий и поднимаю прямо в папке решения всю систему с помощью
docker-compose up -d --build
. У меня на сервере запускаются 3 сервиса: мой, тарантул и монга. 2. Собственно тестирование (build_and_run_test). Если инфраструктура была развёрнута - запускаются все тесты, реализованные в соответствующих проектах, в т.ч. завязанные на базы данных.
У меня реализовано несколько тестов, проверяющих работоспособность тестовой среды и один "содержательный" тест.
При воспроизведении тесты живут в чем-то вроде виртуалки, предоставляемой Github-ом. Известны параметры подключения к сервисам, запущенным на предыдущей стадии, потому с ними можно провзаимодействовать и провалидировать результат.
Если всё ок - job загорается зелёным, нет - красным. К результату можно привязывать различные действия: пропускать коммит в репозиторий, начинать деплой в прод и т.д.
3. Зачистка следов (clear_infrastructure). Вне зависимости от результатов прошлой стадии, останавливаются и удаляются все запущенные на этапе 1 сервисы.
Имея простенький сервер-полигон за 130р/месяц и бесплатный Github actions можно реализовать практически любые свои фантазии по покрытию кода тестами: у меня тестируется только класс для работы с базами.
P.S. Синтаксис в скрипте вида
${{MAIN_HOST}}
- это использование секретов Github actions: хранилища конфиденциальных данных, которым не место в репозитории. Добавляются они через настройки. Туда удобно помещать ssh ключи, адреса серверов, пароли и т.д.#кодинг
#автотесты
#devops
👍1
Наверное главное открытие прошлого года для меня - оркестрация контейнеров с помощью docker compose (в прошлом посте с его помощью я поднимал тестовую инфраструктуру).
В самом начале разработки проекта в Visual Studio я теперь сразу создаю файл docker-compose.yml и запускаю проект для отладки всегда через него, вместе с настроенными игрушечным базами данных, полностью согласованными портами и строками подключения.
А ещё в него можно запихнуть, например, брокер сообщений (RabbitMQ), через которого общаются сервисы. Или фронтенд.
Даже отдельные контейнеры я тоже стараюсь запускать для отладки через compose: для полноты счастья в нем очень удобный механизм передачи переменных окружения, который в случае стандартного докера откровенно убог и неудобен.
В самом начале разработки проекта в Visual Studio я теперь сразу создаю файл docker-compose.yml и запускаю проект для отладки всегда через него, вместе с настроенными игрушечным базами данных, полностью согласованными портами и строками подключения.
А ещё в него можно запихнуть, например, брокер сообщений (RabbitMQ), через которого общаются сервисы. Или фронтенд.
Даже отдельные контейнеры я тоже стараюсь запускать для отладки через compose: для полноты счастья в нем очень удобный механизм передачи переменных окружения, который в случае стандартного докера откровенно убог и неудобен.
Продолжаю своё знакомство (первый опыт контакта был описан в посте про функциональные и интеграционные тесты) с детищем mail.ru - in-memory NoSQL базой данных Tarantool.
In-memory значит, что все данные она держит в оперативной памяти, то есть работает как кэш. Изначально это и был кэш над mysql. Постепенно тарантул мутировал и превратился в настоящего Арагога: под капотом интерпретатор языка Lua для написания хранимок, но можно запросы делать и на sql (к NoSQL базе, да).
Основные отличия от главного конкурента - кэша Redis - состоят в том, что Redis умеет работать как кэш для MongoDB, но при этом тарантул позволяет делать намного более сложные выборки: Redis работает как ключ - значение, то есть, выражаясь языком SQL, у него есть только индексированный primary key.
Тарантул же умеет строить сложносочинённые индексы из многих частей (до 256). Так что если нужны сложные но очень быстрые выборки - тарантул ваш выбор. Для пользователя тарантул не слишком дружелюбен. Впрочем, возможно дело в том, что официальной библиотеки для работы с тарантулом на c# от mail нету. Есть некая опенсорсная поделка, которая работает, и работает нормально, но в использовании она какая-то неудалая.
Данные в тарантуле лежат в space-ах - аналоге sql таблиц в виде кортежей: как строка в таблице. Но, в отличие от sql, жёстко фиксированы типы только столбцов, по которым строятся индексы. В остальных может быть суп из данных. Впрочем, если хочется, можно жёстко задать схему данных при создании space-а.
Индексы в тарантуле могут строиться как по одной "колонке", так и по многим. Составные индексы позволяют делать запросы как по части индекса, так и по значениям для всей строки целиком.
Предположим, хранятся у нас данные вида:
Id, Дата рождения, Фамилия, Имя, Отчество, Должность, Статус (работает/не работает), произвольная информация в следующих колонках. Индекс типа TREE (бинарное дерево под капотом) строится по всем полям, кроме Id. Он сможет отвечать на следующие запросы:
Первое знакомство с тарантулом скорее положительное, работает шустро. Главная претензия к шарповой обертке, там при написании кода получается дикая лапша, а еще без плясок с бубнами мне не удалось отправить в тарантул Guid (uuid, уникальный 128 байтовый идентификатор): превратил в строку, отправил в таком виде на сервер, там распарсил Guid обратно, что конечно дикость, но пока сойдет.
#tarantool
#кодинг
In-memory значит, что все данные она держит в оперативной памяти, то есть работает как кэш. Изначально это и был кэш над mysql. Постепенно тарантул мутировал и превратился в настоящего Арагога: под капотом интерпретатор языка Lua для написания хранимок, но можно запросы делать и на sql (к NoSQL базе, да).
Основные отличия от главного конкурента - кэша Redis - состоят в том, что Redis умеет работать как кэш для MongoDB, но при этом тарантул позволяет делать намного более сложные выборки: Redis работает как ключ - значение, то есть, выражаясь языком SQL, у него есть только индексированный primary key.
Тарантул же умеет строить сложносочинённые индексы из многих частей (до 256). Так что если нужны сложные но очень быстрые выборки - тарантул ваш выбор. Для пользователя тарантул не слишком дружелюбен. Впрочем, возможно дело в том, что официальной библиотеки для работы с тарантулом на c# от mail нету. Есть некая опенсорсная поделка, которая работает, и работает нормально, но в использовании она какая-то неудалая.
Данные в тарантуле лежат в space-ах - аналоге sql таблиц в виде кортежей: как строка в таблице. Но, в отличие от sql, жёстко фиксированы типы только столбцов, по которым строятся индексы. В остальных может быть суп из данных. Впрочем, если хочется, можно жёстко задать схему данных при создании space-а.
Индексы в тарантуле могут строиться как по одной "колонке", так и по многим. Составные индексы позволяют делать запросы как по части индекса, так и по значениям для всей строки целиком.
Предположим, хранятся у нас данные вида:
Id, Дата рождения, Фамилия, Имя, Отчество, Должность, Статус (работает/не работает), произвольная информация в следующих колонках. Индекс типа TREE (бинарное дерево под капотом) строится по всем полям, кроме Id. Он сможет отвечать на следующие запросы:
ФамилияВ вот
Фамилия + Имя
Фамилия + Имя + Отчество
Фамилия + Имя + Отчество + Должность
Фамилия + Имя + Отчество + Должность + Статус
Фамилия + Должность
- уже нет, для такого нужно создавать отдельный индекс или отправляться писать sql-запрос, который отрабатывает медленнее чем lua.Первое знакомство с тарантулом скорее положительное, работает шустро. Главная претензия к шарповой обертке, там при написании кода получается дикая лапша, а еще без плясок с бубнами мне не удалось отправить в тарантул Guid (uuid, уникальный 128 байтовый идентификатор): превратил в строку, отправил в таком виде на сервер, там распарсил Guid обратно, что конечно дикость, но пока сойдет.
#tarantool
#кодинг
Telegram
Эшу быдлокодит
Продолжу затронутую уважаемым @ssleg тему тестов. Я наконец повзрослел и осознал логику организации функциональных и интеграционных тестов.
Если коротко - используем CD/CI (в моем случае Github Actions) для прогона обычных unit-тестов, завязанных на внешние…
Если коротко - используем CD/CI (в моем случае Github Actions) для прогона обычных unit-тестов, завязанных на внешние…
👍5
Начал знакомство с фронтендом: мир ReactJS ждёт.
Особого вдохновения нет, но я хочу стать полноценным фуллстеком, а для этого нужны не только бэкенд язык, базы данных и хотя бы основы девопсовских штучек, но и фронтенд.
Выбрал самый популярный из двух используемых для работы фреймворков (Vue и ReactJS).
Начал знакомство со среды разработки и на этом чуть не сломался: стандартный Visual Studio Code прям очень удручил, в итоге поставил WebStorm и дело сразу пошло.
Особого вдохновения нет, но я хочу стать полноценным фуллстеком, а для этого нужны не только бэкенд язык, базы данных и хотя бы основы девопсовских штучек, но и фронтенд.
Выбрал самый популярный из двух используемых для работы фреймворков (Vue и ReactJS).
Начал знакомство со среды разработки и на этом чуть не сломался: стандартный Visual Studio Code прям очень удручил, в итоге поставил WebStorm и дело сразу пошло.
🔥4👍1💩1
Только я начал нырять в зловонные глубины сайтоделания, как мой хороший знакомый фронтенд-программист завел свой дневничок.
Всецело поддерживаю, дело очень хорошее. Особенно хороша обратная связь от более опытных программистов и возможность вернуться на полгода назад и вспомнить, о чем вообще думал тогда.
Всецело поддерживаю, дело очень хорошее. Особенно хороша обратная связь от более опытных программистов и возможность вернуться на полгода назад и вспомнить, о чем вообще думал тогда.
Telegram
Webdev сохраненки
Tips and tricks и прочие полезности из области веб-разработки, а также репосты понравившихся материалов
Не прошло и двух месяцев, как я начал работать с Тарантулом, и только сейчас я наткнулся на красивое: https://try.tarantool.io/
Песочница для экспериментов с тарантулом для всех желающих. При том - экспериментов в т.ч. взрослых - с настройкой имитации распределенной системы из нескольких тарантулов.
#tarantool
Песочница для экспериментов с тарантулом для всех желающих. При том - экспериментов в т.ч. взрослых - с настройкой имитации распределенной системы из нескольких тарантулов.
#tarantool
👍6
Переписал бота для обратной связи. Старая версия, написанная полтора года назад, перестала работать. С ходу обновить базовую библиотеку для работы с телегой не удалось, потому решил переписать бота с нуля, благо все грабли уже пройдены. Итог - первый мой проект без говнокода (репозиторий), ну если только чуть чуть в юнит тестах.
В качестве базы данных использовал MongoDB. Вместо хранимок, продуманной схемы базы данных, primary и foreign ключей у меня теперь класс на 30 строк, позволяющий положить и прочитать любой другой класс из монги.
Update отдельных полей не предусмотрен, только insert, replace или find. Логика для замены и поиска передаётся в виде лямбда выражения. "Таблицы" - монговские коллекции - создаются по ситуации.
Разумеется, для сложных проектов такой подход не годится. Но вот для простого бота, выполняющего ровно одну задачу - ретрансляцию информации из лички бота в специальную группу - этого более чем достаточно.
#кодинг
В качестве базы данных использовал MongoDB. Вместо хранимок, продуманной схемы базы данных, primary и foreign ключей у меня теперь класс на 30 строк, позволяющий положить и прочитать любой другой класс из монги.
Update отдельных полей не предусмотрен, только insert, replace или find. Логика для замены и поиска передаётся в виде лямбда выражения. "Таблицы" - монговские коллекции - создаются по ситуации.
Разумеется, для сложных проектов такой подход не годится. Но вот для простого бота, выполняющего ровно одну задачу - ретрансляцию информации из лички бота в специальную группу - этого более чем достаточно.
#кодинг
👍8🔥3
Прошли два месяца работы с тарантулом, и я наконец осознал (и отладил) адекватный способ хранить там слабо структурированную информацию: отправлять туда массив байтов byte[] из c#, а внутри тарантула соответствующее поле - string.
Принимать - тоже byte[]. string в тарантуле лежит просто как произвольная последовательность байт. Соответственно, никто не мешает хранить в этой куче байтов guid, который иначе без лишних преобразований из c# в тарантул не прокинуть.
Или - сериализовать в байты структуру (struct в c#, что-то типа класса, но хранится в стеке), или, вообще, использовать protobuf.
#tarantool
#кодинг
Принимать - тоже byte[]. string в тарантуле лежит просто как произвольная последовательность байт. Соответственно, никто не мешает хранить в этой куче байтов guid, который иначе без лишних преобразований из c# в тарантул не прокинуть.
Или - сериализовать в байты структуру (struct в c#, что-то типа класса, но хранится в стеке), или, вообще, использовать protobuf.
#tarantool
#кодинг
👍3
В условиях микросервисной архитектуры важную роль играют брокеры сообщений - обычно RabbitMQ или Kafka.
В кратце, соотношение плюсов и минусов между такое:
RabbitMQ - просто и сердито.
Kafka - сложнее, но лучше масштабируемо + возможность хранить историю прошедших сообщений.
Узнал еще преимущество Kafka: она оказывается умеет напрямую работать с базами данных: MongoDB, Tarantool, PostgreSQL, без самописных прослоек.
В кратце, соотношение плюсов и минусов между такое:
RabbitMQ - просто и сердито.
Kafka - сложнее, но лучше масштабируемо + возможность хранить историю прошедших сообщений.
Узнал еще преимущество Kafka: она оказывается умеет напрямую работать с базами данных: MongoDB, Tarantool, PostgreSQL, без самописных прослоек.
👍3
Впервые нашёл применение такому паттерну синхронизации межпоточного взаимодействия как семафор. Если в 2х словах, он ограничивает число потоков, проходящих через него. Поставил условные 50, и если к нему придут одновременно 1000 потоков, возникнет затор из ожидающих.
Я умудрился положить монгу большим числом параллельных запросов, при некоторых условиях их выстреливало больше 1000 сразу, после чего монга начинала кричать "остановись, демон" и кидала исключение. Семафор на 60 потоков меня спас, теперь всё отлично.
Я умудрился положить монгу большим числом параллельных запросов, при некоторых условиях их выстреливало больше 1000 сразу, после чего монга начинала кричать "остановись, демон" и кидала исключение. Семафор на 60 потоков меня спас, теперь всё отлично.
Docs
Semaphore Class (System.Threading)
Limits the number of threads that can access a resource or pool of resources concurrently.
👍3
Погружаюсь в зловонную яму бездны фронтенда, а если точнее - React.js
Вообще забавно, вроде бы фреймворк и фреймворк. Но по факту - отдельный язык для описания юзер интерфейса. При том, внутри самого реакта есть как минимум два совершенно разных (стилистически) подхода к написанию кода: функциональный и псевдо-ООП.
Пока псевдоООП кажется каким-то уродством, но под него больше примеров и учебников, так что пока кушаю кактус.
#front
#react
Вообще забавно, вроде бы фреймворк и фреймворк. Но по факту - отдельный язык для описания юзер интерфейса. При том, внутри самого реакта есть как минимум два совершенно разных (стилистически) подхода к написанию кода: функциональный и псевдо-ООП.
Пока псевдоООП кажется каким-то уродством, но под него больше примеров и учебников, так что пока кушаю кактус.
#front
#react
👍5
Самый любимый человек - жена - завела канал, про книги, детские и взрослые.
Если кому интересна квантовая механика 0+ или развлекательное фентази - добро пожаловать.
P.S. Мы теперь семья блоггеров:)
Если кому интересна квантовая механика 0+ или развлекательное фентази - добро пожаловать.
P.S. Мы теперь семья блоггеров:)
Telegram
Фига с книгой
О том, как я повелась на рекламу и потом пожалела о покупке книг: часть 1
📚 Крис Ферри "Квантовая физика для малышей", "Электромагнетизм для малышей"
Мой муж физик по образованию. Да и я сама целых три семестра в университете учила физику, на экзаменах…
📚 Крис Ферри "Квантовая физика для малышей", "Электромагнетизм для малышей"
Мой муж физик по образованию. Да и я сама целых три семестра в университете учила физику, на экзаменах…
👍6❤1
В одном чате была затронута тема электробезопасности, потому выложу сюда байку по теме.
В далёкие светлые времена, когда я учился на инженера-оптика, в мае, во время сдачи лабораторных работ, сидел я в лабе и что-то делал за компом. По-моему, колдовал с цифровым осциллографом, но это не точно.
Комп был между двумя лабораторными стендами: здоровенными заземленными чугуниевыми рэльсами, на которых стояли всякие оптические компоненты.
В какой-то момент, пошевелившись, я дотронулся локтями до обоих стендов сразу и меня от души шарахнуло током. Выяснил, что бьётся левый.
Одногруппники мне не поверили, потому трое по очереди брались за стенд под напряжением одной рукой и за "землю" - второй стенд - другой. Все соответственно получили. Откопали мультиметр - померяли - 220В.
Пришел завкаф, принимавший у нас лабы, не поверил. Взялся за стенды и выдал что-то про эмпирический опыт.
Причина нашлась быстро: для простоты подключения земли к стендам его сделали в виде обычной пары вилка-розетка и вот наконец настал момент, когда вилку на одном из стендов воткнули не туда.
В далёкие светлые времена, когда я учился на инженера-оптика, в мае, во время сдачи лабораторных работ, сидел я в лабе и что-то делал за компом. По-моему, колдовал с цифровым осциллографом, но это не точно.
Комп был между двумя лабораторными стендами: здоровенными заземленными чугуниевыми рэльсами, на которых стояли всякие оптические компоненты.
В какой-то момент, пошевелившись, я дотронулся локтями до обоих стендов сразу и меня от души шарахнуло током. Выяснил, что бьётся левый.
Одногруппники мне не поверили, потому трое по очереди брались за стенд под напряжением одной рукой и за "землю" - второй стенд - другой. Все соответственно получили. Откопали мультиметр - померяли - 220В.
Пришел завкаф, принимавший у нас лабы, не поверил. Взялся за стенды и выдал что-то про эмпирический опыт.
Причина нашлась быстро: для простоты подключения земли к стендам его сделали в виде обычной пары вилка-розетка и вот наконец настал момент, когда вилку на одном из стендов воткнули не туда.
🔥19
Эшу быдлокодит
Погружаюсь в зловонную яму бездны фронтенда, а если точнее - React.js Вообще забавно, вроде бы фреймворк и фреймворк. Но по факту - отдельный язык для описания юзер интерфейса. При том, внутри самого реакта есть как минимум два совершенно разных (стилистически)…
Превращение человека в дачника во фронтендера стремительно и необратимо (с)
Вроде бы начал осознавать функциональные компоненты вместе с хранилищем состояний - Redux-ом. А React-то прикольный! Похоже, в стадиях заражения js-ом как мыслевирусом я сразу перепрыгнул на 5ю ступень.
На задворках сознания появилось желание вернуться к диссертации и сделать UI десктопного приложения на связке react + electron.
#front
#кодинг
Вроде бы начал осознавать функциональные компоненты вместе с хранилищем состояний - Redux-ом. А React-то прикольный! Похоже, в стадиях заражения js-ом как мыслевирусом я сразу перепрыгнул на 5ю ступень.
На задворках сознания появилось желание вернуться к диссертации и сделать UI десктопного приложения на связке react + electron.
#front
#кодинг
Хабр
JavaScript как мыслевирус
Вообще я стараюсь не писать статьи и комментарии не на технические темы, но коль скоро появились не совсем технические по духу статьи «JavaScript как явление» и...
👍1