Читать в телеге. Когда-то там были посты не только от меня.
Статическая типизация
Интересная статья про типы. Мне читать было тяжеловато, так как это скорее набор заметок на связанные темы, но в целом статья полезна тем, что перетряхивает имеющиеся знания и заставляет немного подумать.
Прозрачность и обратная связь
В последнее время постоянно натыкаюсь на то, что многим системам не хватает двух вещей: прозрачности и работающей обратной связи. Вроде максимально банальная мысль, но странно, что для многих она не очевидна (ну или я в чем-то сильно заблуждаюсь).
В сложной системе тяжело понять влияние изменений входных данных/сигналов на конечный результат. Если параметры входных данных постоянно меняются (т.е. мы находимся в реальности, а не в оторванном от мира болоте или жесткой мат. модели), то к этим изменениям надо адаптироваться.
Без прозрачности любые изменения похожи на игру в рулетку — что-то меняем в надежде на улучшение результата. Чтобы не делать это вслепую (сюда можно вставить модное “data-driven”), нужно понимать систему, что гораздо проще, если она прозрачна и измеряема. На одной экспертизе, увы, далеко не уедешь, да и знания имеют тенденцию устаревать.
Обратная связь может быть как одним из инструментов измерения, так и инструментом корректировки. И работающая обратная связь сама по себе приводит к большей прозрачности, если она реализована через людей: если предложение сработало, то это должно быть измеримо (иначе следующая ОС будет “вернуть все как было”), а если нет — то должно быть внятное объяснение, почему. Отрицательный результат ОС тоже развивает систему: повышается экспертиза тех, кто давал эту ОС. Как следствие получается, что обратная связь должна быть и на сам процесс обратной связи, т.е. это рекурсивная структура.
Разумеется “работающая” тут неспроста: наличие ОС само по себе не сделает систему лучше.
Шпаргалка по отладке проблем kubernetes
Странноватая блок-схема по решению проблем, но в целом содержит полезную информацию уровня “куда еще стоит посмотреть” и типовые команды для просмотра информации о состоянии кластера. Бонусом идет краткое описание того, как устроен кластер.
В блок-схеме меня позабавили пункты “Unknown state” и “Consult StackOverflow”, да и довольно много информации видно в стандартном дашборде. Но есть и полезное: например, команда kubectl logs <pod-name> --previous
, которая выводит логи предыдущего экземпляра контейнера, пригодится для отладки проблем, когда приложение падает почти сразу после старта.
OWASP наглядно
В продолжение темы про OWASP — можно почувствовать себя кулхацкером скрипт-кидди и посмотреть, как работают OWASP Top-10 “вживую”: https://application.security/free/owasp-top-10. На сайте представлены интерактивные примеры, где подробно разжевывают каждый шаг по эксплуатации уязвимости.
Timeout для команды
Перед любой командой можно приписать timeout Xs
, и она будет завершена после указанного времени, если сама не успела завершиться. Например
timeout 5s yes "I WILL NOT WASTE CHALK"
Причем если команда завершилась по таймауту, то будет специальный код возврата (124), а если успела выполнится сама — ее обычный код. Можно еще менять сигнал с TERM на другой, например на HUP или KILL.
Балансировка в клиенте Elasticsearch
Выбор сервера осуществляется по round robin.
Если выбранный сервер не ответил, то он кладется в бан-лист на минуту, если при следующем запросе не ответил еще раз — примерно на полторы, с увеличением интервала в 2^(failedAttempts/2)
раз вплоть до 30 минут.
Если сервер ответил, то он исключается из черного списка.
Если живых серверов нет, то пробуем самый недавний из черного списка: если и он не отвечает, то все плохо и кидаем исключение.
Напоминает опрос узлов в краулере на старой работе, хотя там реализация была сложнее (хотя бы потому, что проверять надо было как сами сервера, так и прокси), сброс меток был сделан через сброс всего пула, и состояние шарилось между инстансами. Приятно думать, что это было более-менее адекватное решение.
Контексты Painless
В районе версии 6.5 ребята из Elasticsearch что-то сообразили и сделали документацию по контекстам Painless. В ней можно посмотреть, какие переменные доступны в скриптах Painless в зависимости от того, какая операция выполняется — reindex, update by query, скриптованный поиск и т.д. Очень не хватало этого, когда работали с 2-5 версиями и писали всякие миграции на этом “замечательном” языке.
USB-C
Когда пытался понять отличия Thunderbolt 3 от USB 3.X Gen Y Type C, то узнал, что за доставку питания отвечает стандарт USB Power Delivery. И этот стандарт настолько хорош, что можно заряжать телефон от ноутбучной зарядки, если оба этот стандарт поддерживают. Телефон с разъемом USB-C, очевидно, это делает, а на адаптере зарядника от ноута должен быть вариант с 5V/2A. В нормальной технике будет еще защита от неправильных режимов, так что беспокоиться не о чем. Я проверил с рабочим ноутом и телефоном — действительно, работает.
А само отличие Thunderbolt 3 от USB-C в основном заключается в скорости передачи данных и лицензировании (и, как следствие, стоимости). Еще не всякий разъем/кабель USB поддерживает туннелирование сигнала с монитора. Решить это должен USB4, который полностью совместим с Thunderbolt 3 и имеет только один тип разъема, USB-С.
Вообще классно, что через один провод можно передавать любые данные, в т.ч. графику и сеть, а еще и питание. Можно всю периферию и питание цеплять к док-станции, а “тушку” менять — переключаться между рабочим и домашним компом, например. Или вообще телефон воткнуть и работать за ним, как за компом.
Удаление фона
Нашел сайтик, на котором можно без регистрации, смс и прочей фигни удалить фон с изображения, особенно если есть повышенная криворукость, как у меня. Не очень сложный фон удаляется автоматически, а мелкие детали можно подредактировать самостоятельно.
Мне пригодилось для создания эмоджи-реакций в слаке (потому что имеющийся набор очень скуден, особенно после миллиардов стикеров в телеге).
Scala JS
Портировать существующий проект с обработкой заявок на Scala JS оказалось довольно легко (ну, с учетом того, что там нет зависимостей): берем туториал, выполняем немного пунктов из него, меняем немного IO — заменяем чтение из файла на чтение из textarea, аналогично меняем main, добавляем простенькую html-ку и готово. Единственное, обо что споткнулся на первой итерации — нужно было сделать явное преобразование asInstanceOf[TextArea]
после document.getElementById
, но это логично и мелочевка.
На простых примерах работало отлично, на основном примере — подвисло аж на 45 секунд. Браузер трижды предлагал убить скрипт. Размер сборки, кстати — 1.2Мб. Вроде логично: собирал-то я в неоптимизированном варианте, через sbt fastLinkJS
. Для оптимизированной сборки нужно выполнить sbt fullLinkJS
. Результат оптимизации не очень впечатлил — 35 секунд, но зато размер сборки всего 253Кб.
Для сравнения — сборка и запуск с нуля обычной версии (без JS) через sbt clean
+ sbt run
выполнится за 26 секунд, из которых чуть меньше 3 секунд будет само выполнение. Если просто запускать jar, то общее время будет 4 секунды. Тоже многовато, но с учетом числа копирований ради иммутабельности — приемлемо. Может, когда будет настроение, попробую оптимизировать.
В официальных доках пишут, что производительность Scala JS проседает в 1-3 раза по сравнению с обычным кодом. Т.е. мои 11+ раз выглядят весьма тухло.
Я вдумчиво посмотрел в свой код аж пять минут и решил поменять List
на Vector
, потому что у меня есть операции добавления в конец списка, хотя выбор между двумя этими СД довольно трудный (на всякий случай: скаловский Vector
— это хитрый trie, а не динамический массив, как можно подумать по названию). В обычном коде стало только хуже — время возросло до 5 секунд, т.е. стало больше на треть. А вот на фронте снизилось до 6 секунд. Все равно долго, но гораздо лучше, чем 35. И, получается, медленнее обычного кода всего в полтора раза, что укладывается в диапазон 1-3 из официальных бенчмарков. Ускорение спишу на разницу работы с памятью в JVM и JS, подробности оставлю как упражнение читателю :)
Что в итоге получилось — можно посмотреть на гитхабе, рекомендую сразу на первый дифф смотреть.
P.S. по последним постам может показаться, что я мазохист и люблю копаться во фронте, но нет — просто так получилось, что хотелось попробовать, а все руки не доходили (яжбэкендер).