26 августа 2019 – 2 сентября 2019

@eugene_kr

Moscow
26 августа 2019Понедельник
16 твитов
7:55

Всем привет!
На этой неделе с вами я, Евгений Кривобоков (@eugene_kr).
#НоваяАватарка #АвторНедели #день1из7

10:15

Начнем неделю. Сегодня расскажу про сборку приложения.
Будет много капитанства, но это стоит проговорить для полноты картины. #день1из7

10:21

Начать хорошо бы с официальных рекомендаций

12:33

Используем последние версии AGP, Gradle и всех тулзов с кодогенерацией.
Насколько свежие? Выбираем подходящий для команды баланс между стабильностью и новыми фичами.
Вчитываемся в changelog и пробуем.

12:34

"Сделать ли мне "Х", ускорит ли сборку?" - на такой вопрос нет однозначного и простого ответа.
Это гипотеза. Чтобы ее проверить, надо представлять как это работает внутри. Чем лучше мы понимаем внутренности работы, тем более эффективные модели получается строить.

12:36

А что собственно ускоряем? Надо найти где болит и научиться это измерять. Используем github.com/gradle/gradle-….
Сценарии должны отражать типовые изменения в проекте и покрывать оптимизации в системе сборки (изменение ABI, инкрементальность, чистые сборки и т.п.).

12:38

Такие проверки дорогие, поэтому запускаем их уже в develop. Это дает понимание трендов и ловит только очень крупные изменения.
Основная ценность готовых сценариев в другом. Мы упрощаем себе проверку подозрительных изменений, которые влияют на сборку.

16:25

Выносим сборку на более мощную машину: github.com/Instamotor-Lab…
Для мелких изменений иногда медленнее получается, дольше ждем синхронизацию файлов.
Также при изменении структуры модулей может сломать модели проекта для IDE, приходится все чистить.
В целом есть смысл пробовать.

16:31

Для поиска узких мест - build scan scans.gradle.com. Визуализация решает, да и типовые проблемы подсвечивают явно.
Большую часть информации можно достать самостоятельно, через API. Завтра про это подробнее.

17:41

Свежее видео с Droidcon Berlin 2019: droidcon.com/media-detail?v…

19:08

Новый день - новые баги. А ведь только похвалил build scan. Говорят, что слишком много данных засылаем. Видимо это толстый намек на покупку Gradle enterprise. pic.twitter.com/AaMHAH7eGI

20:06

Пару слов про remote cache. Его легко настроить, но все веселье начинается потом. Хорошо если есть Gradle enterpise и он покажет корень проблемы. Но если нет, нужно самому искать.
RTFM: guides.gradle.org/using-build-ca…. С большинством описанных проблем уже столкнулись. А сейчас примеры:

20:15

Прогреваем remote cache на linux (docker) и в OSX, потому что есть баги с переносимостью кеша между ОС (issuetracker.google.com/issues/1267752…)

Написали гит хук, который подчищает пустые директории. Ломалось кеширование после рефакторинга (youtrack.jetbrains.com/issue/KT-27687)

20:21

Как одна оптимизация ломает другую или еще один пример, почему не стоит их включать без проверки (youtrack.jetbrains.com/issue/KT-31511)

Вручную проверяем параметры окружения, версию build tools, не можем зафиксировать (issuetracker.google.com/issues/1177897…). Это тоже нужно для переиспользования кеша.

20:23

И мой любимчик в номинации "веселой отладки, неудачники" thoeni.io/post/macos-sie…

Вот такие трудовые будни. Надеюсь удалось передать почему простые советы плохо работают и нужно разбираться в причинах.

20:56

Просто обязан упомянуть замечательный выпуск @PodlodkaPodcast c @artem_zin : podlodka.tilda.ws/87

Сразу огворюсь, с bazel мало знаком, не могу по существу сравнивать. Затронем еще эту тему при обсуждении CI.

27 августа 2019Вторник
7 твитов
9:19

Сегодня поговорим про метрики сборки и их мониторинг #день2из7

9:34

Собирать данные конечно нужно со всех машин, потому что окружение отличается. К счастью, есть готовые бесплатные решения:

Даже если и решите написать свое, это отличные примеры как добраться до нужных данных.

9:54

У нас свое решение, на порядок упрощенный аналог Talaoit. Из важных показателей:

9:56

Хороший подход - как в build scan, хранить сырые данные по каждой сборке и по ним уже строить агрегаты.

10:04

95 перцентиль pic.twitter.com/33unfs6sxv

13:02

Мы любим fail-fast подход.
Если нашли причину performance деградации и можем ее проверить автоматически, то добавляем в сборку.
Например, если попытаться собрать проект с неподдерживаемой версией Java, то сборка сразу упадет с пояснением причины. Так зачастую дешевле и понятнее.

13:10

Все ошибки сборки перенаправляем в Sentry.
Инструмент как раз под такую модель данных - stacktrace и параметры окружения. pic.twitter.com/ampFjex4ub

28 августа 2019Среда
11 твитов
5:37

Сегодня про Android Studio :harold:
#день3из7

5:41

Какую IDE используете под android?

6:00

Как можем повлиять на IDE?
Как минимум, отключаем все что только можно.
Собрал все что нашли: gist.github.com/eugene-krivobo…

7:14

Когда смотрите время исполнения gradle задач, помните что оно может быть завышено для worker api (github.com/gradle/gradle/…). В AGP 3.5 уже перевели большинство задач (android.enableWorkers).
Помогает другой профайлер - android.enableProfileJson, который показывали на Google IO.

11:10

Узнал лимит для бесплатной версии: 5242880

11:16

Несмотря на Project Marble, AS все еще тормозит как не в себя, особенно в тестах. Мы подумали, что могут быть специфичные проблемы в нашем проекте. Стали проверять разные гипотезы на тестовом проекте. Пример генератора, чтобы с нуля не начинать: github.com/android/androi…

11:19

На тестовых проектах все отлично, как бы ни пытались их усложнять. Были разные гипотезы: количество модулей, какие-то фичи языка, тяжелые инспекции, lint проверки и т.п. Ничего из этого не получилось достоверно подтвердить.

11:20

Пока подтвердилось очевидное: размер classpath.
Если модулю доступно много классов, это негативно влияет.
Пример бага на эту тему: issuetracker.google.com/issues/1331242…

12:46

Когда все плохо и AS не справляется с крупными изменениями в проекте (mirakle в пример), либо реимпортируем проект, либо вручную чистим .iml модели.

Например, вот так: git.io/fjxI1
(скрипт в стиле дешево и сердито, только ради примера)

13:45

Если синхронизация проекта не прошла успешно, то AS может запустить совсем не ту задачу, которая указана в конфигурации.
Проверить можно во вкладке Build | Build Output. В начале лога будет Executing tasks: [assemble]. Без конкретного модуля, значит запустит все с таким именем.

14:12

Достали сообщения "WARNING: The option setting '...' is experimental and unsupported."? На каждый модуль?!
Отключаем с помощью android.suppressUnsupportedOptionWarnings.

И голосуем про похожий шум в котлин плагине: youtrack.jetbrains.com/issue/KT-33065

29 августа 2019Четверг
17 твитов
8:44

Поговорим про жизнь маленького коммита в CI

#день4из7

8:50

Пару лет назад наш CI был очень простой. Мы смотрели на опыт других компаний. Здесь хочу упомянуть старую и все еще полезную публикацию от facebook: research.fb.com/publications/c…
В итоге многое вышло довольно похожим.

9:30

По мере роста команды и с жаркими спорами пришли к trunk based модели ветвления. Хорошо масштабируется.
Качественный обзор: trunkbaseddevelopment.com
После такого даже нечего добавить.

12:55

По верхам про инфаструктуру.
Все android приложения живут в монорепозитории. Любой исполняемый в CI код - в docker, все это крутится в kubernetes. Для CI используем TeamCity.

12:57

Все изменения проходят через pull request'ы.
Задача CI - обеспечить "стабильный" trunk. Соответственно, набор проверок подбираем сравнивая их стоимость и закрываемые риски. Универсальных рецептов нет.
Запускаем:

12:58

Юнит теcты не параллелим. Нет необходимости, потому что модули уже довольно мелкие и хорошо параллелится на этом уровне.
Также юнит тесты хорошо кешируются в gradle. Еще один довод в пользу remote cache.

12:59

lint гонять по всем модулям нет смысла, дает ложно-положительные ошибки.
Поэтому выгоднее только по приложениям, но с зависимостями checkDependencies (в lintOptions).

13:01

Если lint слишком медленный, попробуйте настройки:

  • checkGeneratedSources
  • checkTestSources
  • ignoreTestSources
  • checkReleaseBuilds

Подробнее почитать про борьбу за performance и медленные проверки можно здесь:
groups.google.com/forum/#!topic/…

13:08

Чтобы сократить объем проверок, в тестировании есть практика impact analysis. Ее можно автоматизировать для тестов.
Описание концепции: martinfowler.com/articles/rise-…
Для android тестов, в привязке к модулям: youtu.be/EBO2S9qcp0s?t=…

16:11

Важная концепция - IaC (en.wikipedia.org/wiki/Infrastru…)
CI - это не инфраструктура "сбоку", это часть проекта.
Все изменения - через PR, версии не разъезжаются, сборки получаются более воспроизводимые.

16:16

Всю логику CI пишем в Gradle плагинах.
Получаем готовое решение для:

16:17

Плагины покрываем интеграционными тестами (docs.gradle.org/current/usergu…).
Как это выглядит:
Генерируем в тесте git репозиторий с небольшим многомодульным проектом. К нему применяем плагин, кусочек CI. Прогоняем разные сценарии. Зачастую даже удается test first применять.

16:26

Любопытная задача: как держать в монорепозитории тесты, которые проверяют этот же репозиторий, целиком?

Для этого в тесте копируем репозиторий, и натравливаем на копию Gradle Tooling API (docs.gradle.org/current/usergu…).
Позволяет снаружи получить модель проекта и позапускать задачи.

17:34

У каждой автоматизации своя цена, порой высокая. Мы не умеем проверять в PR абсолютно все инфраструктурные изменения.
Для этого есть чеклисты с тем, что не забыть при изменения в критичных частях.
Большинство пунктов - запускаешь проверки вручную, глазами оцениваем результаты.

19:12

Часть проверок слишко дорогие для PR, никакого железа не хватит.
Например, e2e тесты на разных версиях SDK.
Запускаем все проверки после слияния в develop, некоторые вообще только ночью.
Утром команды разбирают найденные баги, чтобы поправить их до релиза.

19:16

CD тоже затрону. Уже несколько месяцев делаем canary релизы в android.
Чередуем: одна неделя - полный регресс, другая - катим после авто-тестов.
Теперь изменения доезжают в среднем на 5 дней быстрее. Чтобы не пострадало качество, пытаемся сравнивать метрики между релизами.

19:20

До полной автоматизации еще далеко, все равно приходится приглядывать за метриками и крешами.
Но даже если canary релиз остановлен из-за багов, обратная связь от него все равно полезна. Находим проблемы раньше.
И на команду меньше давления, если не успели, через неделю доедет.

30 августа 2019Пятница
9 твитов
9:11

Продолжаем про CI, сфокусируемся на UI тестах #день5из7

9:43

UI тесты пишут все, кто коммитит в код приложений. Для команды это только один из инструментов, как обеспечить необходимое качество и скорость разработки.
Отличный обзорный доклад про это: youtu.be/25EO8E3DMPw

10:06

github.com/avito-tech/and… - наша обертка над espresso.
Пишу не с таким посылом, чтобы все пользовались, а чтобы заинтересовать вас проблемами в espresso. Сталкиваемся с ними даже в самых простых действиях, что делает тесты нестабильными. Защищаемся тремя слоями синей изоленты.

10:22

Главная проблема с e2e тестами - стабильность. Любая проблема в сервисах сказывается на тестах.
Перезапуски теста сами по себе не помогают.
Ключевая идея: сравнивать результаты прогона на feature ветке и в trunk. Только после этого смогли сделать UI тесты блокирующими в PR.

10:30

Метафора: нестабильность инфраструктуры размениваем на время проверок.

10:38

Абсолютно стабильные e2e тесты - это недостижимый идеал.
Их задача в PR: убедиться что наши изменения _не сделали хуже_. Иначе мы просто остановим разработку из-за проблем в любом сервисе.
Поэтому оставляем сценарии, когда может просочиться нестабильное.
Выбрали такой баланс.

13:26

А вот так тесты запускаются в CI pic.twitter.com/gQov7KyEhT

13:27

Это пример подхода, когда клиент резервирует и управляет эмуляторами.
Альтернатива - общая очередь. Эффективнее, но сложнее и более хрупко.
Коллеги для iOS написали такую очередь - emcee: git.io/fjxDr

31 августа 2019Суббота
10 твитов
7:34

Хотели бы больше делиться решениями по инфраструктуре.
Считаем что нам это будет только в плюс.
Осталось найти время и удобные форматы.
Смотрели на git.io/fjxu9 - громоздко, удорожает изменения и не факт что переиспользуемо.
Посоветуйте хорошие примеры и практики

7:40

На выходные оставил легкую тему, про branch by abstraction #день6из7

7:45

Заезженная и очевидная тема. Тем не менее, решил рассказать, потому что в последнее время спрашивали.
Эта практика одна из основных, которая помогла сократить время релиза с месяцев до недель. Необходимая, но конечно не достаточная.

martinfowler.com/articles/featu…

14:02

Обязаны ли команды использовать тоглы?
Нет, это не самоцель.
Задача следующая: нестабильная фича не должна блокировать релиз.

14:02

Теперь каждое изменение закрывать тоглом? Даже мелкий bugfix?
Решение за командой. По опыту, лучше закрыть тоглом, даже bugfix. Особенно если его тяжело воспроизвести или исправляешь в спешке.

14:03

Все ли можно закрыть тоглом? Нет.
Если в compile time меняем что-то, получим другой бинарник на выходе. В runtime уже не поменять.
Если слишком дорого, тоже можем принять риск и катить без тогла.

14:04

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

14:12

Пример заботы о пользователях, который кажется в AGP встречал.

14:19

Обзорный доклад про то, как пришли к этому, как используем, и про свое решение для удаленного управления.
Не смотрите что про iOS, почти все совпадает.
youtu.be/wxB6Vzo_Xzc

14:24

Считаю ошибкой, что сделали отдельное решение для удаленного управление тоглами, не смогли объединить с сплит-тестами. Это должен быть один продукт, во всех смыслах.

1 сентября 2019Воскресенье
10 твитов
5:03

"Лучше работать завтра, чем сегодня!"
#день7из7

7:40

5 сентября будет ровно 5 лет, как я работаю в Авито.
Пришел вторым android разработчиком, еще совсем зеленым.
За это время многое изменилось, да и компания стала другой.

7:41

Как и зачем работать в одной компании 5 лет?
У меня нет ответа для всех. Упомяну лишь пару идей. Не воспринимайте их за абсолют.

7:42

Необходимо менять проекты, технологии, зоны ответственности. Заниматься чем-то одним рано или поздно надоест, каким-бы интересным это не было.
За последние пару лет перестал писать продуктовый код, ознакомился с разными технологиями, попробовал себя в роли тимлида и вернулся.

7:43

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

9:11

А что вы писали запоминающегося в рабочие чаты? pic.twitter.com/A2Wa2vowea

9:18

Расскажу про свое хобби - rope-jumping
Что мне это дает:

15:30

10 != 11
26 октября 2018 прилетел в Амман на прыжки, долго не мог понять, почему никого нет и рейсы какие-то странные.
Оказалось, что перепутал месяц и все прилетают 26 ноября.
Интересно было наблюдать за собой в миниатюре фазы отрицания, гнева, ...
И такое бывает

15:47

С вами интересно, мне понравилось, но пора передавать эстафету.
Спасибо @igrekde за приглашение!

Остаёмся на связи.
telegram: @EKrivobokov

2 сентября 2019Понедельник
3 твита
3:57

С вами на линии @igrekde с минуткой рекламы – ведь что может быть лучше утром в понедельник!

3:58

В московский офис Indriver открыты вакансии синьора и мидла айосера. У ребят 29млн пользователей и супер интересные задачи, которые делают жизнь этих людей лучше.
За подробностями – sakhayaana в Телеграме.
hh.ru/vacancy/329245…

4:07

И пора брать билеты на осенний @AppsConfRussia – конфу, которая помогает мобильным разработчикам расти.
И там можно будет вживую послушать многих авторов этого твиттера, например: @0leGG @nekdenis @ZiminAlex @M0rtyMerr @posipov @sboishtyan