Читать в телеге. Когда-то там были посты не только от меня.
Hello world на kotlin native
- Скачиваем релиз, распаковываем.
- Запускаем
kotlinc-native -help
:
Error occurred during initialization of VM
Could not reserve enough space for 3145728KB object heap
- Офигеваем от того, что этой штуке нужно 3 гига, запускаем с ограничением:
_JAVA_OPTIONS="-Xmx256M" kotlinc-native -help
- Делаем 1.kt с чем-то похожим на котлиновский код:
fun main() {
println("https://t.me/minutkaprosvescheniya/120")
}
- Пробуем скомпилировать:
_JAVA_OPTIONS="-Xmx256M" kotlinc-native 1.kt -o 1
- Офигеваем от того, что надо скачать “немного” зависимостей — 600 мегабайт (в 2000-х за такое расстреляли бы).
- Офигеваем от того, что виртуалка у нас немного старая, i386, и kotlin-native поддерживается для arm32, win x86, watchOs x86, wasm32, MIPS, умных часов, но не для linux 32-bit, мол никому не надо — тебе надо, ты и делай.
- Повторяем шаги 1-6 для компа поновее.
- Офигеваем от того, что нельзя никак убрать расширение
.kexe
, потому что “это хороший способ идентифицировать файлы”. - Запускаем
./1.kexe
, получаем результат. - Продолжаем офигевать от зрелости технологии.
Состояния процесса в linux
Когда-то давно я думал, что root
всемогущ и может убить любой процесс. Однако если процесс находится в состоянии Uninterruptible Sleep (оно же D), то он может так конкретно повиснуть, что поможет только перезагрузка, о чем даже в отделе травили страшилки на вечер пятницы:) А происходит это из-за того, что процесс ждет I/O и на сигналы не реагирует. И если что-то пошло не так, то так он и будет висеть до следующей перезагрузки, несмотря ни на что (такое было на проде).
В новом дивном мире ты просто редеплоишь докер-контейнер в кубере, но на нем свет клином не сошелся.
Подробнее про состояние процессов можно почитать в статье.
Как тестировать работу с реляционной БД
Самые банальные варианты включают в себя:
- Тестирование на тестовом стенде (для особых извращенцев — на общем стенде, для супер-извращенцев — резервирование ресурса путем устных переговоров с коллегами, ну а у темных властелинов тестовый стенд — это прод).
- Тестирование с БД, которая разворачивается локально (возможно даже сама, возможно в докер-контейнере).
- Тестирование с in-memory аналогом.
С первым пунктом все понятно, а вот между другими двумя надо думать.
С одной стороны, завязываться на реализацию БД как-то странно, особенно с учетом того, что вряд ли к базе идет обращение напрямую, а не через ORM и/или DSL, и может еще и через liquibase. С другой — эти абстракции дырявые, и тот же liquibase поле с типом TEXT создаст как TEXT (он же VARCHAR) в Postgresql, но как CLOB в H2. Вдобавок, у различных СУБД есть свои “особенности”, от которых не всегда получится абстрагироваться — помню как года 4 назад во времена импортозамещения у меня пригорело от того, что Oracle не различает пустую строку и null. Вдобавок всякие статьи говорят о том, что не-не, нельзя делать unit-тесты c in-memory H2, если у вас на проде Postgresql, у вас прод сгорит и вообще мы все умрем.
В моем идеальном мире все СУБД и прослойки для общения с ними написаны нормально и такие проблемы не должны возникать. В чуть менее идеальном — эти отличия несущественные и легко проверяются интеграционными тестами, если надо поддерживать несколько СУБД, или влияют только на производительность, но не на интерфейсы/поведение.
Но этой заметки не было бы, если бы не потекшие абстракции: при обновлении H2 столкнулся с проблемой, что они решили кидать исключение про то, что не поддерживают индексы на CLOB поля (хотя раньше просто ничего не делали). И вот сошлись звезды в лице связки liquibase + H2, и несмотря на то, что никакие нестандартные вещи не использовались, все поломалось. Конкретно в этом кейсе удалось извернуться, но ситуация насторожила: получается, что SQL не такой уж и стандарт…
Полезные и не очень сайты для curl
Полезные:
- https://httpbin.org/ — универсальная штука для отладки HTTP-клиента. Самый частый кейс у меня был
curl https://httpbin.org/ip
, но подойдет для кейсов, когда надо выяснить, что ваш клиент сует в данные кроме того, что сказали (например, какой user-agent). - https://restcountries.eu/ — выводит основные данные о стране:
curl -s https://restcountries.eu/rest/v2/name/russia
.
И среднего уровня бесполезности:
- Погода:
curl -s http://wttr.in
- Зойдберг:
curl zoidberg.live
- Fuck off as a service, местами может заменить httpbin:
curl 'https://www.foaas.com/zero' -H'Accept: application/json'
- Ну и классика — Звездные Войны, можно сделать аналог самостоятельно:
curl https://asciitv.fr
Mock и Wiremock
Сейчас довольно популярно тестирование с моками — объектами-заглушками, имитирующими реальное поведение чего-либо. Для любителей ФП звучит дико, конечно: зачем что-то имитировать для чистых функций?
К сожалению, не всегда все так радужно, и в ООП-шном коде с кучей DI, IoC и прочими SOLIDами для простого юнит-теста придется пол-графа зависимостей поднимать. Вот и получаются моки, которые по сути работают как перехватчики входов-выходов для нужного метода. А нормальные интеграционные тесты делать дорого и они существенно замедляют билд.
Добавьте сюда еще микросервисы и получится, что надо имитировать и проверять HTTP-вызовы. Появляется специальный web-сервер, вся задача которого — отдавать заранее заготовленный ответ на нужный вызов и записывать все обращения. В качестве примера можно привести WireMock. Хотя если такая штука нужна на 1 раз, то, имхо, гораздо проще взять первый попавшийся скрипт на питоне, поднимающий локальный HTTP, и вкорячить туда нужное, чем возиться с настройкой чего-то посложнее.
Пагинация в SQL
Годная статья про пагинацию в SQL, где рассказано про варианты ее реализации. С алгоритмической сложностью!
Покрытие тестами схем Camunda
Дабы связать воедино дебри рефлексии, прикол про стулья, запуск чего-то после всех тестов, другую смешнявку и минутку про Camunda, выкладываю презентацию доклада о задаче, которая это все породила.
Припудрю это своим нытьем про java.
Когда делал пулл-реквесты в опенсорсную библиотеку, пришлось писать на java7. В комбинации с местами не очень продуманным кодом это вызвало у меня страдания. Тонны копипасты. Куча бойлерплейта по перекладыванию из одного слоя абстракции в другой. Куча приватных методов, в которых закопано все нужное. Фабрики. Мне действительно пришлось делать фабрику (с интерфейсом для фабрики, с изменением класса для прокидывания фабрики и изменением билдера для класса), потому что по-другому в существующую реализацию и не вкорячишься.
Работа с коллекциями это вообще ад. Мало того, что все надо делать тупыми циклами, так еще и нет элементарных методов типа getOrDefault
.
Конечно, если ОЧЕНЬ НАДО, то что-то написать можно. Но плакать и колоться так каждый день лично я не готов даже за большие деньги…
Нюансы sendmail
Испокон веков одним из стандартов общения операционной системы с пользователем была электронная почта. Я не настолько старый, чтобы это застать, но во времена, когда работать надо было через терминал на сервере, где кроме тебя еще куча пользователей, и личных компов не было, это наверно было удобно.
Работает это довольно просто — глобально настраивается почтовый сервер, а дальше отдаешь команду вроде
echo "hello" | sendmail general@kenobi.sw
И все, письмо ушло адресату. Звучит весьма клево, но внимательный читатель должен был триггернуться на “глобально”.
Недавно выяснилось, что сервер, где такое настроено, выжирает дневной лимит писем в 50к за сутки, хотя предполагаемая нагрузка — 10 писем в день. Виртуалка выключена админами, и в голове мечутся мысли: взломали? Но кому такое надо? Может, ПО, использующее sendmail, сошло с ума?
Однако после разбирательств выяснилось, что столько писем слал… cron
. По умолчанию поведение системы такое, что любой stdout от него шлется пользователю на почту. Но на какую почту, ее же наверно надо задать? Разумеется, тут все предусмотрено: на почту user@host, и плевать, что она не существует. А как себя ведет себя с письмом на несуществующий адрес почтовый сервер? Правильно, пытается послать до посинения.
А надо было всего лишь отредактировать /etc/sysconfig/crond
, чтобы отключить отправку на почту и включить редирект в syslog:
CRONDARGS=-s -m off
рестартнуть crond
и почистить очередь:
exim -bp | exiqgrep -i | xargs exim -Mrm
Вы все еще любите глобальные настройки? Тогда мы идем к вам:)
Факторизация чисел
Иногда складывается ощущение, что в командной строке есть вообще все. Как import antigravity.
Наткнулся недавно абсолютно случайно на команду для факторизации чисел:
$ factor 1224234
1224234: 2 3 3 3 3 3 11 229
$ factor 24342342342342342342342342534512312123
24342342342342342342342342534512312123: 11 43053238739605007 51400086909245973599
$ factor 243423423423423423423423425345123121241
factor: ‘243423423423423423423423425345123121241’ is too large
BPMN-нотация и Camunda
Business Process Model and Notation — еще один способ описания алгоритма или процесса в виде схемы. Разрабатывался с прицелом на то, чтобы нотация была понятна и бизнесу, и разработчикам, и даже менеджерам. TLDR в виде cheatsheet.
Продолжением этой идеи являются BPMN-движки: чтобы схема была не только в документации, но по ней генерировалсь и само управление процессом, вместо какого-нибудь самопального конечного автомата. Звучит неплохо: аналитик нарисовал, разработчик интегрировал где надо, и все готово. Реальность, конечно, немного посложнее, и код все равно надо будет писать. Как и с любым фреймворком, нужно потратить некоторое время на его изучение, за абстракции придется платить производительностью, а при столкновении с ограничениями придется выдумывать костыли. Однако разработку это неплохо ускоряет и плюшка в лице наглядности довольно значимая.
Один из самых популярных BPMN-движков сейчас — это Camunda. Оперсорс, Java, REST API, внутренний API, web-морда для админки — вот, наверно, основные ключи к успеху в текущих реалиях индустрии.
Подробнее про все это можно почитать, например, в блоге о BPMN.