ݺߣ

ݺߣShare a Scribd company logo
Tofu и его окружение
Шелопугин Кирилл
О чём поговорим
• Что такое Tofu
• Зачем оно нужно?
• Из чего состоит Tofu
• Немного о его ингридиентах
• Немного (много) об Env
О чём не поговорим
• Что такое тайпклассы
• Что такое Cats/Cats-Effect
• Что такое Tagless-Final
Что такое Tofu?
• Набор инструментов для удобного ФП
• Множество удобных абстракций
• Родился из внутренних fputils
• Отлично сочетается с Tagless-Final стилем
• https://github.com/TinkoffCreditSystems/tofu/
• Production-ready, чистое value!
Зачем нужно Tofu
• Несовершенство текущей иерархии тайпклассов Cats/Cats-Effect
• Есть вопросы к расположению тайпклассов в иерархии
• Многие тайпклассы слишком «сильны»
• Более точный контроль над кодом/эффектами
Зачем нужно Tofu
Зачем нужно Tofu
Что включает в себя Tofu?
• env-monad
• optics
• memoization
• config
• logging
• атомарные тайпклассы (Context, Timeout, Raise, etc.)
Tofu-core
• Ядро tofu
• Содержит множество полезных тайпклассов и абстракций
• Абстрагировано от конкретных монад
• Предоставляет инстансы либо способы создания
Tofu-core: Fire/Race/Start
Позволяют:
• запускать вычисления в фоне с игнорированием результата
• запускать вычисления в фоне с возможностью получения
результат
• запускать несколько параллельных вычислений, возвращая
первое
Tofu-core: Fire/Race/Start
Tofu-core: Fire/Race/Start - пример
Tofu-core: обработка ошибок
Raise:
• Позволяет прерывать цепочку вычислений (monadic fail-fast)
• Можно создать инстанс для любого ApplicativeError
Tofu-core: обработка ошибок - пример
Tofu-core: обработка ошибок - пример
Tofu-core: обработка ошибок - пример
Tofu-core: Timeout
• Позволяет прерывать вычисление после заданного интервала
• Есть инстанс для cats.effect.IO
• Можно создать инстанс для любого cats.effect.Concurrent
Tofu-core: Context
• Легковесная версия ApplicativeAsk
• Описывает вычисление, имеющее неизменяемый контекст
• Широко используется в tofu-logging и Env
Tofu-core: Context - пример
Tofu-core
А также множество других полезных тайпклассов для F:
• GenUUID для генерации случайных UUID
• Lift/Unlift как аналог FunctionK[F, G] и замена cats.effect.Effect
• Тайпклассы для работы с HKT
• Аналоги Alternative из Cats
• и многое другое!
Tofu-logging
• Реализация логирования на тайпклассах
• Операции представлены в виде алгебры
• Логирование – это эффект!
• Структурное логирование
• Синтаксис со строковой интерполяцией
• Логирование контекста
Tofu-logging: базовый пример
Tofu-logging: базовый пример
• Создание инстанса Logging – тоже эффект!
• Инстансы создаются поименно либо для класса (сервиса)
Tofu-logging: Loggable и LoggedValue
Tofu-logging: Loggable и LoggedValue
Tofu-logging: Loggable
• Тайпкласс
• Описывает, как значение должно быть записано в log message
• Описывает, как значение должно быть записано в «контекст»
• «Контекст» – слабая форма построения JSON (addString, addInt,
etc.)
• Контекст может быть использован для чего угодно – ELK layout,
JSON, GELF, etc.
• Неявно конвертируется в LoggedValue
Tofu-logging: Loggable
• инстансы для примитивов
• базовые инстансы для коллекций
• инстансы, выводящиеся из других
Tofu-logging: Loggable - пример
Tofu-logging: Loggable - syntax
• вы тоже устали от logger.{info|error|etc.}?
• мы идём к вам!
• просто добавь воды сахарка синтаксиса
• сам подхватит Logging из скоупа
• сам попросит Loggable для всех параметров
• сделает всё не всё за вас
Tofu-logging: Loggable - syntax
Tofu-logging: Loggable - пример
• Расширяем Loggable
• Добавляем ELKLayout
Tofu-logging: Loggable - пример
Env-монада
• Монада для передачи «окружения» произвольному вычислению
• Доступ к контексту в любое время вычисления
• Прозрачная передача
• Вычислительный примитив – Monix Task
• Умеет всё, что умеет Task
Env-монада — зачем?
• Зачастую необходимо передавать вычислению контекст
• Логирование
• Использование в вычислениях
Env-монада — зачем?
• Можно передавать через implicit параметр
• Не очень удобно везде прокидывать параметр
• Можно забыть про него
Env-монада — зачем?
• Можно передавать через ThreadLocal/TaskLocal/etc.
• Для Future — написать свой ExecutionContext
• Плюсы для Future:
• boilerplate отсутствует
• Минусы для Future:
• Писать свой ExecutionContext
• Следить за context propagation на границе между Future и не-Future
(например, Akka) и прокидывать руками
• Сложно контролировать, контекст появляется «из воздуха»
Env-монада — зачем?
• Можно передавать через ThreadLocal/TaskLocal/etc.
• Для Monix Task — использовать TaskLocal
• Плюсы для Task:
• boilerplate меньше
• более приемлемый контроль над тем, где контекст есть, а где - нет
• Минусы для Task:
• boilerplate с параметрами всё равно есть - TaskLocal нужно передавать
параметром по коду
• отслеживание на границах с другими моделями исполнения всё равно есть
Env-монада — что предлагает?
l Прозрачная передача контекста
l Все функции «знают», что работают в некотором контексте
l Функции композируются
l Возможно переопределить контекст для локального скоупа
l Никаких сюрпризов с «потерянным» контекстом
Env-монада — что предлагает?
Env-монада — что умеет?
l Работа с сайд-эффектами
l Работа с чистыми значениями
l Создание из других типов (Try/Either/Future/IO)
l Наличие tailRecM
Env-монада — что умеет?
Env-монада — что умеет?
l Обработка ошибок
l Повторы в случае ошибок
l Обработка с учётом контекста
Env-монада — что умеет?
l Доступ к контексту in a monadic way
l Возможность переопределить контекст для локального скоупа
l Контроль над параллелизмом «из коробки»
l Мемоизация
l Таймауты
Env-монада — пример
Env дружит с tofu-logging!
l Один раз определить имплисит
l Показать, как контекст может быть вытащен и использован
l …
l Контекст автоматически вытаскивается и записывается в лог
l PROFIT!
l Документация с примерами интеграции coming soon!
Итоги
• Если вы пишете в Tagless-Final стиле – обязательно попробуйте
Tofu
• Если вы не пишете в Tagless-Final стиле, но вам нужны вычисления
с контекстом – попробуйте Tofu
• Если вы пишете код на Future – обязательно попробуйте Tofu и
Env/Task
• Если вы пишете код на акторах - Бог вам судья!
Вопросы?
email: kshelopugin@gmail.com
k.shelopugin@tinkoff.ru
Scala Russia tg: https://t.me/scala_russia
PONV: https://t.me/scala_ponv

More Related Content

Tofu и его окружение

  • 1. Tofu и его окружение Шелопугин Кирилл
  • 2. О чём поговорим • Что такое Tofu • Зачем оно нужно? • Из чего состоит Tofu • Немного о его ингридиентах • Немного (много) об Env
  • 3. О чём не поговорим • Что такое тайпклассы • Что такое Cats/Cats-Effect • Что такое Tagless-Final
  • 4. Что такое Tofu? • Набор инструментов для удобного ФП • Множество удобных абстракций • Родился из внутренних fputils • Отлично сочетается с Tagless-Final стилем • https://github.com/TinkoffCreditSystems/tofu/ • Production-ready, чистое value!
  • 5. Зачем нужно Tofu • Несовершенство текущей иерархии тайпклассов Cats/Cats-Effect • Есть вопросы к расположению тайпклассов в иерархии • Многие тайпклассы слишком «сильны» • Более точный контроль над кодом/эффектами
  • 8. Что включает в себя Tofu? • env-monad • optics • memoization • config • logging • атомарные тайпклассы (Context, Timeout, Raise, etc.)
  • 9. Tofu-core • Ядро tofu • Содержит множество полезных тайпклассов и абстракций • Абстрагировано от конкретных монад • Предоставляет инстансы либо способы создания
  • 10. Tofu-core: Fire/Race/Start Позволяют: • запускать вычисления в фоне с игнорированием результата • запускать вычисления в фоне с возможностью получения результат • запускать несколько параллельных вычислений, возвращая первое
  • 13. Tofu-core: обработка ошибок Raise: • Позволяет прерывать цепочку вычислений (monadic fail-fast) • Можно создать инстанс для любого ApplicativeError
  • 17. Tofu-core: Timeout • Позволяет прерывать вычисление после заданного интервала • Есть инстанс для cats.effect.IO • Можно создать инстанс для любого cats.effect.Concurrent
  • 18. Tofu-core: Context • Легковесная версия ApplicativeAsk • Описывает вычисление, имеющее неизменяемый контекст • Широко используется в tofu-logging и Env
  • 19. Tofu-core: Context - пример
  • 20. Tofu-core А также множество других полезных тайпклассов для F: • GenUUID для генерации случайных UUID • Lift/Unlift как аналог FunctionK[F, G] и замена cats.effect.Effect • Тайпклассы для работы с HKT • Аналоги Alternative из Cats • и многое другое!
  • 21. Tofu-logging • Реализация логирования на тайпклассах • Операции представлены в виде алгебры • Логирование – это эффект! • Структурное логирование • Синтаксис со строковой интерполяцией • Логирование контекста
  • 23. Tofu-logging: базовый пример • Создание инстанса Logging – тоже эффект! • Инстансы создаются поименно либо для класса (сервиса)
  • 26. Tofu-logging: Loggable • Тайпкласс • Описывает, как значение должно быть записано в log message • Описывает, как значение должно быть записано в «контекст» • «Контекст» – слабая форма построения JSON (addString, addInt, etc.) • Контекст может быть использован для чего угодно – ELK layout, JSON, GELF, etc. • Неявно конвертируется в LoggedValue
  • 27. Tofu-logging: Loggable • инстансы для примитивов • базовые инстансы для коллекций • инстансы, выводящиеся из других
  • 28. Tofu-logging: Loggable - пример
  • 29. Tofu-logging: Loggable - syntax • вы тоже устали от logger.{info|error|etc.}? • мы идём к вам! • просто добавь воды сахарка синтаксиса • сам подхватит Logging из скоупа • сам попросит Loggable для всех параметров • сделает всё не всё за вас
  • 31. Tofu-logging: Loggable - пример • Расширяем Loggable • Добавляем ELKLayout
  • 32. Tofu-logging: Loggable - пример
  • 33. Env-монада • Монада для передачи «окружения» произвольному вычислению • Доступ к контексту в любое время вычисления • Прозрачная передача • Вычислительный примитив – Monix Task • Умеет всё, что умеет Task
  • 34. Env-монада — зачем? • Зачастую необходимо передавать вычислению контекст • Логирование • Использование в вычислениях
  • 35. Env-монада — зачем? • Можно передавать через implicit параметр • Не очень удобно везде прокидывать параметр • Можно забыть про него
  • 36. Env-монада — зачем? • Можно передавать через ThreadLocal/TaskLocal/etc. • Для Future — написать свой ExecutionContext • Плюсы для Future: • boilerplate отсутствует • Минусы для Future: • Писать свой ExecutionContext • Следить за context propagation на границе между Future и не-Future (например, Akka) и прокидывать руками • Сложно контролировать, контекст появляется «из воздуха»
  • 37. Env-монада — зачем? • Можно передавать через ThreadLocal/TaskLocal/etc. • Для Monix Task — использовать TaskLocal • Плюсы для Task: • boilerplate меньше • более приемлемый контроль над тем, где контекст есть, а где - нет • Минусы для Task: • boilerplate с параметрами всё равно есть - TaskLocal нужно передавать параметром по коду • отслеживание на границах с другими моделями исполнения всё равно есть
  • 38. Env-монада — что предлагает? l Прозрачная передача контекста l Все функции «знают», что работают в некотором контексте l Функции композируются l Возможно переопределить контекст для локального скоупа l Никаких сюрпризов с «потерянным» контекстом
  • 39. Env-монада — что предлагает?
  • 40. Env-монада — что умеет? l Работа с сайд-эффектами l Работа с чистыми значениями l Создание из других типов (Try/Either/Future/IO) l Наличие tailRecM
  • 42. Env-монада — что умеет? l Обработка ошибок l Повторы в случае ошибок l Обработка с учётом контекста
  • 43. Env-монада — что умеет? l Доступ к контексту in a monadic way l Возможность переопределить контекст для локального скоупа l Контроль над параллелизмом «из коробки» l Мемоизация l Таймауты
  • 45. Env дружит с tofu-logging! l Один раз определить имплисит l Показать, как контекст может быть вытащен и использован l … l Контекст автоматически вытаскивается и записывается в лог l PROFIT! l Документация с примерами интеграции coming soon!
  • 46. Итоги • Если вы пишете в Tagless-Final стиле – обязательно попробуйте Tofu • Если вы не пишете в Tagless-Final стиле, но вам нужны вычисления с контекстом – попробуйте Tofu • Если вы пишете код на Future – обязательно попробуйте Tofu и Env/Task • Если вы пишете код на акторах - Бог вам судья!
  • 47. Вопросы? email: kshelopugin@gmail.com k.shelopugin@tinkoff.ru Scala Russia tg: https://t.me/scala_russia PONV: https://t.me/scala_ponv