?

Log in

No account? Create an account
Дважды мудак — ЖЖ [entries|archive|friends|userinfo]
Декларативное рулит

Site Meter

[ website | Мой сайт ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

I have never encountered this in any other language [июл. 5, 2019|13:20 pm]
Andy Melnikov
[Tags|, , ]

https://github.com/haskell/haskell-ide-engine/issues/1302

TLDR: всем похуй на потребление памяти
Ссылка28 комментариев|Оставить комментарий

Посадил дерево! [июн. 27, 2019|11:31 am]
Andy Melnikov
[Tags|, , ]

Написал Monad tutorial.
Ссылка4 комментария|Оставить комментарий

Минимальный пример курильщика [июн. 25, 2019|13:35 pm]
Andy Melnikov
[Tags|, ]

Сейчас обнаружилась на стейджинге аномалия. Минимальный датасет, на котором воспроизводится баг - 100 метров (40 в архиве). Ну то есть надо забирать к себе и пускать инструментированную версию системы, дабы понять, где жопа, и сконструировать пример меньшего размера.
Ссылка1 комментарий|Оставить комментарий

Открыл для себя заново IDE [июн. 14, 2019|14:47 pm]
Andy Melnikov
[Tags|, , ]

Я тут несколько недель бьюсь с багом моей системы поиска дубликатов через Bloom filters. Почему-то часть входных данных пропадает, не попадая ни в "хорошие", ни в "плохие".

В процессе поиска бага перевёл компонент на TS и основательно его порефачил. В TS тоже, после JS, "если билдится после рефакторинга - значит работает". Не так конечно как в х-е, но в сравнении с ЖС бомба.

Затем перевёл его в студию. Студия и так была заведена, просто для других проектов, то есть сетап занял минимальное время.

Сегодня с утра решил, что надо писать доку. Решил писать в формате не "как устроено", а

1. какая задача стоит
2. как можно было бы сделать
3. почему сделано не так, как можно было бы, а так, как сделано

В процессе придумывания, как описать задачу в одно предложение для дебилов, понял, что хорошо бы ввести 3 определения и получилось:

{Component name} is a tool to filter out records having non-unique Z. For example, if more than one record has Z, then the output should not contain _any_ record with Z.

А дальше псевдокодом, используя комбинации слов из текста в качестве идентификаторов, написал на псевдокоде алгоритм.
foreach (record in dataset) {
   Z = extractZ(record)
   if (hasUnique(Z)) {
      keep(record)
   }
   else {
      filterOut(record)
   }
}
На самом деле текста и кода поболее, но они не прошли цензуру NDA. Но суть та же. Далее я замечаю, что в один проход не выйдет реализовать hasUnique(), поэтому нужен доп. проход:
allZ = empty
foreach (record in dataset) {
   allZ += extractZ(record)
}
Ну и дальше если allZ у нас например мультисет - то hasUnique реализуется тривиально. Но такой подход не работает потому что нас порвёт по памяти.

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

А для этого хорошо бы привести для начала имеющийся код в соответствие с терминологией документа.

И тут меня понесло. В результате вот наивную версию я так и не получил, но код стал намного более понятным, за счёт смены терминов на не содержащие деталей реализации, и разнесение кода непосредственно дедупликации от кода составления отчётов.

Насчёт IDE - те примитивные рефакторинги, которые поддерживаются (cross-module rename, move definition to a separate file, extract function) - ужасно полезны на практике.

И ещё открыл для себя киллер-фичу - студия в тултипе показывает tsdoc даже по локальным идентификаторам. Ну и в reasonably sized tooltip помещается овердохуя информации, 2 коротких предложения - запросто.

Другая подсветка unreachable code и unused identifiers (привет любителям расцвечивать всё только регулярками) - тоже внезапно полезна при работе с всякими подгнившими кодобазами.

Upd: выяснил тут, что я не дебил - наивная реализация на маленьких файликах правильно классифицирует, но на средних очень быстро создает Map на 3.6 гб и падает. Хез почему именно 3.6.
Ссылка11 комментариев|Оставить комментарий

Стабильные версии [июн. 10, 2019|13:30 pm]
Andy Melnikov
[Tags|, ]

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

Есть "книжное" понятие стабильной версии здорового человека: делаем новую ветку мастера с feature freeze и только фиксим баги. Через какое-то время в этой ветке оказывается нечего чинить: всё починили, остались только баги, на которые всем похуй, новые баги обнаруживаются редко. Код стабилизировался.

Такие "настоящие" стабильные версии попадаются крайне редко, обычно разные вариации стабильной версии курильщика.

1. Замораживание перед релизом.

Это наиболее частая форма стабилизации, в особенности перед первым релизом. Часто это не для стабилизации вовсе - просто все заебались и хотят релизиться, но QA не пускает. Если QA нет - это внутреннее чувство прекрасного, не позволяющее релизить совсем уж говно и/или заказчик, от которого надо получить бабло и забыть проект как страшный сон.

2. Замораживание перед деплоем

Это наиболее характерно для проектов в стадии поддержки.

3. LTS-ветки

Надо понимать, что LTS-ветки - это просто замороженные ветки. Они обретают некоторую степень стабильности лишь через некоторое время, когда наиболее значительные баги там обнаружат и пофиксят. Ну то есть идея "обновиться на свежевышедшую LTS-ветку" это ужас-ужас.

4. Бэкпорт-ветки

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

Допустим, у нас в проекте есть подсистема из говна. Мы делаем ветку, и затем в мастере заменяем её на подсистему из шоколада. В случае LTS-ветки баги в системе из говна чинятся. А в случае бэкпорт-ветки - нет.

Идея бэкпортов в том, что бэкпорты очень дёшевы. Кроме того они встречаются в сценариях, когда веток как таковых нету.

5. Погонять на стейджинге

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

6. Погонять на продакшене и если поломалось - откатить

Это вариация 5, но более экстремальная (во всех смыслах).

7. Погонять на продакшене и если поломалось - починить по-быстрому, если не получилось - откатить

И тут как раз мы приходим к первому абзацу поста. Если откатывать - то куда? Надо помечать годные ревизии.

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


Преимущества такие:
- получается человекочитаемые имена версиям давать в виде даты. Благо двух версий в один день не бывает
- не бывает такого, что версия, помеченная как стабильная, становится нестабильной (может когда-то и бывает, но у меня не было)
- между стабильными версиями нетехнический ченжлог - то есть не бывает такого, что весь ченжлог - это шишку где-то в кишках поменяли на мышку, как правило есть какие-то видимые фичи и улучшения
- виден долгосрочный прогресс - условно, сколько обновлений в год
- всё вышеперечисленное не замусоривается хотфиксами
Ссылка10 комментариев|Оставить комментарий

navigation
[ viewing | most recent entries ]
[ go | earlier ]