Lil Functor
795 subscribers
57 photos
1 file
183 links
Pure functional and composable channel

Чат: https://t.iss.one/+L-xb_m_4lnY3Y2Fi
Download Telegram
Забавный блогпост от SoftwareMill о том, как дефолтные настройки кафки ломают её гарантию сохранения порядка сообщений в одной партиции.

Вроде как все знают, что если нужен порядок, то надо ставить
max.in.flight.requests.per.connection=1
(или отключать ретраи продюсера). Но дефолтный конфиг, нарушающий одну из гарантий системы — это странно.

https://blog.softwaremill.com/does-kafka-really-guarantee-the-order-of-messages-3ca849fd19d2
Собрал материалы по инъекции зависимостей в скале c ZIO. ZLayer пока совсем свежая технология, поэтому систематических обучающих материалов по ней пока нет. Но уже набралось приличное количество руководств от разных авторов.

Документация

ZLayer
Use modules and layers
Macros

Блогпосты

🛠Adam Warski — Managing dependencies using ZIO
🛠Pavels Sisojevs — From idea to product with ZLayer
🛠aappddeevv — zio layers and framework integration
🛠Tim Pigden — Example of ZLayers being used in combination
🛠Juliano Alves — ZIO + Http4s: a simple API client

Слайды к докладам

👨‍🎓Adam Fraser — Solving The Dependency Injection Problem With ZIO
👨‍🎓Pierangelo Cecchetto — Ray tracing with ZIO-ZLayer
В последнем письме рассылки Scala Times пришла ссылка на ютуб, где чувак рассказывает про opaque types в скале. Оказалось, что у него куча видео с лекциями на канале. Рассказывает про языковые фичи, функциональное программирование, популярные библиотеки, тулинг.

У него отличная манера говорить, и на всех видео открыт редактор с кодом, где он демонстрирует то, о чём говорит. Канал — настоящая жемчужина для тех, кто вкатывается в скалку.

https://www.youtube.com/channel/UCSBUwLT9zXhUalKfJrc2q2A
У зио очередной патч к релиз-кандидату вышел
Хорошая статья с чеклистом для ревью кода внутри распределённых систем.

Обращение к сторонним компонентам
- обрабатываются ли все ошибки, прописано ли восстановление после ошибок?
- закрываются ли ресурсы в случае ошибок, откатываются ли изменения состояния?
- есть ли таймаут на обращение к другому компоненту? обрабатывается ли таймаут отдельно от остальных ошибок?
- есть ли ретраи на таймауты?
- ограничивается ли нагрузка при ретраях (экспоненциальные ретраи, circuit breaker)?
- в случае использования batch API, ограничен ли размер батча?
- кешируются ли ответы?

Разработка API
- идемпотентно ли API?
- ограничено ли время ожидания ответа?
- может ли API работать батчами? ограничен ли размер принимаемого батча?
- собираются ли логи/метрики обращений к API?
- какой статус должен получить клиент в случае отказа отдельных этапов обработки запроса?
- не протекают ли доменные модели между частями системы?

Ещё у автора есть пост по дизайн ревью новых компонентов системы: https://www.kislayverma.com/post/design-review-checklist-for-distributed-systems
Нередко в айтишных чатах появляются люди, заявляющие о бесполезности хаскеля в промышленной разработке ПО и отсутствии реальных проектов на нём. Это воспринимается как троллинг, но на самом деле всё гораздо сложнее. Весь расчёт идёт на то, что вспыльчивые хаскеллисты в качестве доказательства применимости любимого языка скинут обидчику исходные коды закрытых рабочих проектов. Будьте осторожны и не путайте т.н. «троллинг» с промышленным шпионажем!
Завтра в 20:00 по Москве на шестичасовом воркшопе нас научат делать DI на скале через фреймворк distage. Мне вот по izumi стеку ничего не понятно, но очень интересно. Поэтому жду с нетерпением.

Зарегистрироваться: https://ziverge.zoom.us/meeting/register/tZMucemoqT4iHtaI84z8tJdQfKYl2Wpbnmje?timezone_id=Europe%2FMoscow
Копаясь в скала-коде восьмилетней выдержки, узнал, как раньше скалисты парсили json. Был в стандартной библиотеке модуль parser-combinators для описания разного рода грамматик. Ну а в нём, соответственно, готовый парсер json.

Как можно представить json в языке с сильной системой типов и мощным компилятором? Через ADT, покрывающее типами все возможные варианты значений? Можно, но есть вариант попроще — Map[String, Any]. А массив джсонов — List[Any].

Ну и функция для парсинга, возвращающая Option[Any], где в Any может быть либо Map[String, Any], либо List[Any] 😊. Не смотрел по истории коммитов, был ли уже в стандартной библиотеке на момент написания этого кода тип Either, но вряд ли он бы сильно помог. Короче, такое вот тайплевельное программирование на максимуме, это вам не в circe кодеки макросами выводить.

Сейчас всё это дело удалено из стд, задепрекейчено и остаётся висеть на гитхабе артефактом древних времён https://github.com/scala/scala-parser-combinators/tree/1.1.x
Ехал Any через Any
Вчера вышел релиз ZIO 1.0, и по этому поводу Дегуз написал большой блогпост про разработку библиотеки от прототипа до консалтинговой компании. История подробная, с упоминанием основных технических решений, их мотивации, и людей, работающих над ними. Редко получается проследить историю развития софта в живом рассказе, а не по коммитам.

https://ziverge.com/blog/zio-1.0/
Я сделал ещё один канал, на который буду сбрасывать понравившуюся мне музыку. Преимущественно электронная сцена. Существенную часть этой музыки я слушаю во время работы, так что может быть другим программистам она тоже будет интересна.

Милости прошу к своей кибердиджейке — @choreus
Нашёл маленький, едва заметный шанс на то, что в третьей скале исправят одну из самых раздражающих меня штук:

Option(42).fold(Nil)(x => List(x, x, x)) // not compiles


Тут компилятор выводит тип результата по первому списку аргументов как Nil, и не может догадаться, что List[Int] является его супертипом. В итоге приходится писать тип руками

Option(42).fold(List.empty[Int])(x => List(x, x, x))


Удручает то, что в пулл-реквесте с исправлением не было коммитов с мая, но вдруг случится чудо https://github.com/lampepfl/dotty/pull/9076

Ещё там подробно и простым языком расписано решение, так что можно понять, что происходит, не разбираясь в кишках компилятора.
Забавные коаны про гит. О консистентности комманд прямо в точку

https://stevelosh.com/blog/2013/04/git-koans
Не люблю зашитые в код недетерменированные функции, например, получение текущего времени. В передовых методиках функционального программирования можно заинъектить часы в код через F[_]: Clock или ZIO[Clock, E, A], но даже без них гораздо лучше сделать

trait Clock {
def nanoTime(): Long
}


и прокидывать в свои классы его, а не хардкодить там System.nanoTime.

Тогда в тестах можно будет подставить константу вместо настоящего времени и проверить, что она корректно прописывается во все нужные места.

Аналогично для всяких рандомов, гуидов и прочего.
Ух ты, что есть — анимированная документация по основным комбинаторам ZIO

https://zio.surge.sh/

Покрыты пока далеко не все фичи, но особенно на Schedule выглядит очень наглядно
Очень подробный рассказ про конкарренси под капотом у скаловых монадок. Понятно расписано, как работают легковесные потоки (файберы) поверх jvm-тредпулов, сами тредпулы, и как всё это взаимодействует с нашими цепочками .flatMap. Более цельной и детальной информации на эту тему пока не видел, автор определённо заслуживает звёздочки на гитхабе 😉

https://github.com/slouc/concurrency-in-scala-with-ce