Хорошая статья с чеклистом для ревью кода внутри распределённых систем.
Обращение к сторонним компонентам
- обрабатываются ли все ошибки, прописано ли восстановление после ошибок?
- закрываются ли ресурсы в случае ошибок, откатываются ли изменения состояния?
- есть ли таймаут на обращение к другому компоненту? обрабатывается ли таймаут отдельно от остальных ошибок?
- есть ли ретраи на таймауты?
- ограничивается ли нагрузка при ретраях (экспоненциальные ретраи, circuit breaker)?
- в случае использования batch API, ограничен ли размер батча?
- кешируются ли ответы?
Разработка API
- идемпотентно ли API?
- ограничено ли время ожидания ответа?
- может ли API работать батчами? ограничен ли размер принимаемого батча?
- собираются ли логи/метрики обращений к API?
- какой статус должен получить клиент в случае отказа отдельных этапов обработки запроса?
- не протекают ли доменные модели между частями системы?
Ещё у автора есть пост по дизайн ревью новых компонентов системы: https://www.kislayverma.com/post/design-review-checklist-for-distributed-systems
Обращение к сторонним компонентам
- обрабатываются ли все ошибки, прописано ли восстановление после ошибок?
- закрываются ли ресурсы в случае ошибок, откатываются ли изменения состояния?
- есть ли таймаут на обращение к другому компоненту? обрабатывается ли таймаут отдельно от остальных ошибок?
- есть ли ретраи на таймауты?
- ограничивается ли нагрузка при ретраях (экспоненциальные ретраи, circuit breaker)?
- в случае использования batch API, ограничен ли размер батча?
- кешируются ли ответы?
Разработка API
- идемпотентно ли API?
- ограничено ли время ожидания ответа?
- может ли API работать батчами? ограничен ли размер принимаемого батча?
- собираются ли логи/метрики обращений к API?
- какой статус должен получить клиент в случае отказа отдельных этапов обработки запроса?
- не протекают ли доменные модели между частями системы?
Ещё у автора есть пост по дизайн ревью новых компонентов системы: https://www.kislayverma.com/post/design-review-checklist-for-distributed-systems
Kislay Verma
Code review checklist for distributed systems | Kislay Verma
A basic checklist for reviewing code in a distributed systems environment
Нередко в айтишных чатах появляются люди, заявляющие о бесполезности хаскеля в промышленной разработке ПО и отсутствии реальных проектов на нём. Это воспринимается как троллинг, но на самом деле всё гораздо сложнее. Весь расчёт идёт на то, что вспыльчивые хаскеллисты в качестве доказательства применимости любимого языка скинут обидчику исходные коды закрытых рабочих проектов. Будьте осторожны и не путайте т.н. «троллинг» с промышленным шпионажем!
Завтра в 20:00 по Москве на шестичасовом воркшопе нас научат делать DI на скале через фреймворк distage. Мне вот по izumi стеку ничего не понятно, но очень интересно. Поэтому жду с нетерпением.
Зарегистрироваться: https://ziverge.zoom.us/meeting/register/tZMucemoqT4iHtaI84z8tJdQfKYl2Wpbnmje?timezone_id=Europe%2FMoscow
Зарегистрироваться: https://ziverge.zoom.us/meeting/register/tZMucemoqT4iHtaI84z8tJdQfKYl2Wpbnmje?timezone_id=Europe%2FMoscow
Forwarded from Scala Nishtyaki Channel
У скалалаза появился теперь свой канал, где можно и посмотреть тлдр о выпуске и даже прослушать его; жойнитесь!
https://t.iss.one/scalalaz_podcast
https://t.iss.one/scalalaz_podcast
Telegram
Scalalaz Podcast audio feed
постим сюда копии аудио - пока в ручную
Кстати говоря у нас есть репа https://github.com/scalalaz-podcast/scalalaz-gen/ так что если есть опечатки или еще какие проблемы, можно и пры делать и ишши создавать
Кстати говоря у нас есть репа https://github.com/scalalaz-podcast/scalalaz-gen/ так что если есть опечатки или еще какие проблемы, можно и пры делать и ишши создавать
Копаясь в скала-коде восьмилетней выдержки, узнал, как раньше скалисты парсили json. Был в стандартной библиотеке модуль parser-combinators для описания разного рода грамматик. Ну а в нём, соответственно, готовый парсер json.
Как можно представить json в языке с сильной системой типов и мощным компилятором? Через ADT, покрывающее типами все возможные варианты значений? Можно, но есть вариант попроще —
Ну и функция для парсинга, возвращающая
Сейчас всё это дело удалено из стд, задепрекейчено и остаётся висеть на гитхабе артефактом древних времён https://github.com/scala/scala-parser-combinators/tree/1.1.x
Как можно представить 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
Вчера вышел релиз ZIO 1.0, и по этому поводу Дегуз написал большой блогпост про разработку библиотеки от прототипа до консалтинговой компании. История подробная, с упоминанием основных технических решений, их мотивации, и людей, работающих над ними. Редко получается проследить историю развития софта в живом рассказе, а не по коммитам.
https://ziverge.com/blog/zio-1.0/
https://ziverge.com/blog/zio-1.0/
Я сделал ещё один канал, на который буду сбрасывать понравившуюся мне музыку. Преимущественно электронная сцена. Существенную часть этой музыки я слушаю во время работы, так что может быть другим программистам она тоже будет интересна.
Милости прошу к своей кибердиджейке — @choreus
Милости прошу к своей кибердиджейке — @choreus
Нашёл маленький, едва заметный шанс на то, что в третьей скале исправят одну из самых раздражающих меня штук:
Тут компилятор выводит тип результата по первому списку аргументов как
Удручает то, что в пулл-реквесте с исправлением не было коммитов с мая, но вдруг случится чудо https://github.com/lampepfl/dotty/pull/9076
Ещё там подробно и простым языком расписано решение, так что можно понять, что происходит, не разбираясь в кишках компилятора.
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
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 выглядит очень наглядно
https://zio.surge.sh/
Покрыты пока далеко не все фичи, но особенно на Schedule выглядит очень наглядно
Очень подробный рассказ про конкарренси под капотом у скаловых монадок. Понятно расписано, как работают легковесные потоки (файберы) поверх jvm-тредпулов, сами тредпулы, и как всё это взаимодействует с нашими цепочками
https://github.com/slouc/concurrency-in-scala-with-ce
.flatMap. Более цельной и детальной информации на эту тему пока не видел, автор определённо заслуживает звёздочки на гитхабе 😉https://github.com/slouc/concurrency-in-scala-with-ce
GitHub
GitHub - slouc/concurrency-in-scala-with-ce: Introduction to concepts of asynchronous and concurrent programming in Scala, based…
Introduction to concepts of asynchronous and concurrent programming in Scala, based on the Cats Effect library. - slouc/concurrency-in-scala-with-ce
Forwarded from PONV Daily (Oleg ℕizhnik)
Долгий интересный разговор про использование ReasonML в продакшене, и почему не тайпскрипт (потому что ансаунд). ResonML — это попытка фейсбука адаптировать OCaml под нужды фронтенда. Синтаксис, конечно, испортили скобочками, но в остальном это тот же самый окамл.
При попытках работать с тайпскриптом меня удручала его «особенность» компилировать код, в котором типы на самом деле не сходились. На втором месте по уровню раздражения была необходимость постоянно помогать компилятору в местах, где он не может вывести типы. Ризон этих проблем лишён, но количество программистов на рынке, конечно, хех мда.
https://www.youtube.com/watch?v=nZDN6XCM1X0
При попытках работать с тайпскриптом меня удручала его «особенность» компилировать код, в котором типы на самом деле не сходились. На втором месте по уровню раздражения была необходимость постоянно помогать компилятору в местах, где он не может вывести типы. Ризон этих проблем лишён, но количество программистов на рынке, конечно, хех мда.
https://www.youtube.com/watch?v=nZDN6XCM1X0
YouTube
TypeScript - это трата времени. Год с #ReasonML на продакшене
Почему TypeScript - трата времени, Flow чуть получше, но все равно победил ReasonML? Про сильные стороны и фейспалм.
Антон Тужик, Frontend Developer из SEMrush рассказывает про год использования ReasonML в продакшене.
00:00 - Вступление
00:33 - Из геолога…
Антон Тужик, Frontend Developer из SEMrush рассказывает про год использования ReasonML в продакшене.
00:00 - Вступление
00:33 - Из геолога…
Alexandru Nedelcu опубликовал блогпост с размышлениями о flow-sensitive typing на примере старого-доброго
Такое активно используется в тайпскрипте и котлине.
И что могу сказать: ДА, ОЧЕНЬ ХОЧЕТСЯ. Казалось бы, уже в 2.13 появились literal types, а в третьей скале будут дизъюнкции типов. Поэтому есть надежда, что через какое-то время отпадёт необходимость запрещать
https://alexn.org/blog/2020/11/12/i-like-option-get.html
Option#get из скалы. Если вкратце, flow-sensitive typing — это когдаif (option.nonEmpty) {
println(option.get) // ← проходит проверку компилятора
} else {
println(option.get) // ← упадёт с ошибкой
}Такое активно используется в тайпскрипте и котлине.
И что могу сказать: ДА, ОЧЕНЬ ХОЧЕТСЯ. Казалось бы, уже в 2.13 появились literal types, а в третьей скале будут дизъюнкции типов. Поэтому есть надежда, что через какое-то время отпадёт необходимость запрещать
Option#get в линтерах.https://alexn.org/blog/2020/11/12/i-like-option-get.html
Роб Норрис опубликовал маленькую библиотечку, которая умеет получать название типа в рантайме. Такая легковесная альтернатива TypeTag для логирования типа выражения.
Тем более библиотека состоит из макроса на три строчки, который можно просто стащить себе в проект.
https://github.com/tpolecat/typename
И, раз такое дело, грех не вспомнить библиотеку sourcecode, которой очень удобно вытаскивать названия функций и автоматически подставлять их в названия метрик.
@ import org.tpolecat.typename._
import org.tpolecat.typename._
@ def log[T](expr: T)(implicit typeName: TypeName[T]): String = s"expression of type ${typeName.value} with value ${expr}"
defined function log
@ log(List(1, 2, 3))
res3: String = "expression of type List[Int] with value List(1, 2, 3)"Тем более библиотека состоит из макроса на три строчки, который можно просто стащить себе в проект.
https://github.com/tpolecat/typename
И, раз такое дело, грех не вспомнить библиотеку sourcecode, которой очень удобно вытаскивать названия функций и автоматически подставлять их в названия метрик.
Увидел в канале про Rust (кстати, рекомендую) пост о том, как сделать паттерн-матчинг строк с выделением их составных частей. Например, разматчить строку по известному префиксу: https://t.iss.one/dereference_pointer_there/1366
Задумался о том, как написать то же самое в скале. Оказалось, что с 2.13 уже и писать ничего не надо: в стандартной библиотеке есть решение для матчинга не просто префиксов, а любых частей интерполированных строк!
Задумался о том, как написать то же самое в скале. Оказалось, что с 2.13 уже и писать ничего не надо: в стандартной библиотеке есть решение для матчинга не просто префиксов, а любых частей интерполированных строк!
"I love Scala" match {
case s"I $feeling $language" => Map(language -> feeling)
case other => Map.empty
}
Работает эта радость за линейное время по вот такому алгоритму: https://research.swtch.com/globTelegram
Блог*
#prog #rust #моё
В Rust есть такая удобная вещь, как сопоставление с образцом (pattern matching), и она работает в том числе и для строк. К сожалению, оно позволяет сопоставлять только строки целиком, но не по частям. В частности (no pun intended), match…
В Rust есть такая удобная вещь, как сопоставление с образцом (pattern matching), и она работает в том числе и для строк. К сожалению, оно позволяет сопоставлять только строки целиком, но не по частям. В частности (no pun intended), match…