Минутка просвещения

Читать в телеге. Когда-то там были посты не только от меня.

Чек-лист тимлида

Хорошая статья, которая пригодится не только всяким руководителям, но и каждому в команде. В ней рассмотрены типичные боли проекта и команды с позиции "что можно улучшить новому руководителю", но можно использовать ее как источник идей для того, что можно улучшить в команде самостоятельно. Содержит жизы :)

СсылкаКомментировать

16 Кб хватит всем

У докера обнаружилась веселая особенность: он разделяет строки лога длиной более 16 Кб, чтобы оптимизировать использование буфера. Настроить размер нельзя. При разбиении лог помечается как разделенный, и подразумевается, что склейка должна быть на стороне агрегатора логов (причем есть несколько их реализаций). Однако не все агрегаторы это адекватно поддерживают: например, Filebeat не может это сделать для двух записей из разных файлов (в разные файлы они могут попасть при ротации логов).

СсылкаКомментировать

Google Calendar API

Писал скриптик заполнения командного гугл-календаря. API вроде простое, но нужно пройти N кругов ада, чтобы создать приложение и получить на него креды, с которыми хоть что-то можно сделать. Конечно, классно, что я из коробки могу следить за использованием приложения, квотами, запустить его в облаке, управлять биллингом и все такое... но это поганый скрипт, который мне надо запускать раз в месяц примерно. Прокликивать ради этого больше трех инструкций — как-то стремно.

И поскольку гугл заботится о своих пользователях, то нельзя просто так взять и разрешить какому-то приложению подключиться к календарю. Во-первых, нужно его опубликовать и пройти модерацию (альтернатива — работать в тестовом режиме, что я и выбрал). Во-вторых, нужно получить разрешение у каждого пользователя — тоже логично, но вот только разрешение дается на ограниченный период времени. В моем случае это было 2-3 дня, т.е. при каждом использовании скрипта приходится заново давать ему разрешение в браузере.

Наконец, аутентификация и авторизация должны быть по последнему слову техники, поэтому процесс в совокупности занимает 9 "простых" шагов. Изначально я рассчитывал собрать скрипт из говна и палок на requests, как это делал для Upsource, но пришлось использовать гугловые библиотеки, ибо такую шляпу реализовывать ради скрипта — безумие. Никаких тебе basic-auth или "получи токен 1 раз и делай что хочешь".

Итого, с одной стороны, все логично: безопасно для пользователя, удобно для крупных приложений. А с другой — у меня есть логин-пароль к этому календарю, я и так с ним могу сделать что угодно — зачем городить огород для "владельца" ресурса?

P.S. Кажется, стоит вводить рубрику #пригорело, но тогда половина постов с ней будет :)

СсылкаКомментировать

Нюансы работы ImageMagick с PDF

Convert (ImageMagick) — классная утилита для преобразования изображений, но настройки по умолчанию для PDF там не очень хорошие. Поэтому стоит указывать такие параметры как density (DPI), compress jpeg (чтобы выходной pdf был не гигантским) и quality (чтобы определить степень "мыла"). Например, так:

convert -density 288 -quality 80 -compress jpeg page*.pdf combined.pdf

Кроме того, иногда бывают проблемы с потреблением ресурсов — тогда стоит отредактировать /etc/ImageMagick-*/policy.xml и повысить лимиты.

СсылкаКомментировать

Raft

Raft — алгоритм решения конфликтов в распределенных средах. Считается более понятной альтернативой семейству протоколов Paxos. Познакомиться на наглядных примерах с самой проблемой консенсуса и алгоритмом можно тут, а для закрепления можно помоделировать разные ситуации на основном сайте.

Различные реализации этого алгоритма используются в etcd (т.е. и в Kubernetes тоже), Docker swarm, Consul, Kafka (там называется KRaft), Hazelcast, RethinkDB, Aeron. У него довольно много реализаций. Например, команды HashiСorp, RabbitMQ и Redis делали его реализации, не связанные с основными продуктами, но с оглядкой на них.

СсылкаКомментировать

Порядок запуска тестов

Юнит-тесты на то и "юнит", что они изолированы от всего и независимы от всего. Они должны себя вести одинаково в любое время дня, в любой временной зоне, в любой день, в любой год. И разумеется, порядок их запуска не должен иметь значения.

Но только не в мире Spring. При запуске тестов средствами Spring, контекст приложения, созданный в тесте, кэшируется и может быть переиспользован в одном из следующих тестов. Казалось бы, хорошая оптимизация: не нужно каждый раз дорого создавать контекст, все тесты прогоняются быстрее. Но из-за этого надо пристально следить за тем, чтобы контекст оставался чистым. Особенно, если есть какие-нибудь синглтоны или статические классы.

Так-то в любых плюс-минус интеграционных тестах надо следить за тем, чтобы удалить все ненужное и почистить за собой. Но Spring добавляет немного безумия в эту схему: многое начинает еще зависеть от того, когда в контексте появились ссылки на используемые объекты и когда контексты переключаются между собой. И тут порядок запуска тестов начинает иметь значение: от него зависит переключение контекстов. По умолчанию тесты запускаются в порядке файловой системы — очень весело потом выяснять причину упавшего на билд-сервере теста.

И до этого были flaky-тесты в проекте, но обычно их можно было лениво решить через @DirtiesContext и отложить выяснение корневой проблемы на потом. Но на прошлой неделе наступили на грабли посерьезнее, и даже эта анноташка не помогала. Проблема в итоге обнаружилась в движках Camunda (их было два: для интеграционного теста и для теста логики и проверки покрытия), которые перетирали друг друга. Решилось все назначением отдельного имени для второго движка, но осадочек остался: даже чтобы воспроизвести проблему и локализовать ее, потребовалось много времени.

Поэтому поперек всех best practices поставили алфавитный порядок запуска тестов, хотя бы чтобы воспроизвести локально было легче.

СсылкаКомментировать

Прозрачность и обратная связь

В последнее время постоянно натыкаюсь на то, что многим системам не хватает двух вещей: прозрачности и работающей обратной связи. Вроде максимально банальная мысль, но странно, что для многих она не очевидна (ну или я в чем-то сильно заблуждаюсь).

В сложной системе тяжело понять влияние изменений входных данных/сигналов на конечный результат. Если параметры входных данных постоянно меняются (т.е. мы находимся в реальности, а не в оторванном от мира болоте или жесткой мат. модели), то к этим изменениям надо адаптироваться.

Без прозрачности любые изменения похожи на игру в рулетку — что-то меняем в надежде на улучшение результата. Чтобы не делать это вслепую (сюда можно вставить модное "data-driven"), нужно понимать систему, что гораздо проще, если она прозрачна и измеряема. На одной экспертизе, увы, далеко не уедешь, да и знания имеют тенденцию устаревать.

Обратная связь может быть как одним из инструментов измерения, так и инструментом корректировки. И работающая обратная связь сама по себе приводит к большей прозрачности, если она реализована через людей: если предложение сработало, то это должно быть измеримо (иначе следующая ОС будет "вернуть все как было"), а если нет — то должно быть внятное объяснение, почему. Отрицательный результат ОС тоже развивает систему: повышается экспертиза тех, кто давал эту ОС. Как следствие получается, что обратная связь должна быть и на сам процесс обратной связи, т.е. это рекурсивная структура.

Разумеется "работающая" тут неспроста: наличие ОС само по себе не сделает систему лучше.

СсылкаКомментировать