Обзоры видео на технические темы, январь-сентябрь 2016

Каждый рабочий день, в обеденный перерыв, у меня есть 15-20 минут на просмотр видео. Читать в этот момент не удобно, это отвлекает от процедуры поглощения пищи, а видео в самый раз.

Впечатления от видео за январь-октябрь этого года в этом посте. В последующем планирую переодически делать такие обзоры.

Предыдущий похожий обзор – Видео со ScalaDays 2015 San Francisco.

Scala Monads: Declutter Your Code With Monadic Design – Dan Rosen

  • общие слова про монады, flatmap и map
  • примеры на scalaz
  • Хороший вывод в конце - монады что-то прячут, заменяя это на типы. Option прячет boilerplate от "if non-null" logic, Validation – try/catch и т.д.

The Multi-threading, Non Blocking IO – Heinz Kabutz

Live coding сессия. Объясняется способ написать сервер: блокирующий, неблокирующий на nio, с тредами или с селекторами. Интересно.

Scalaz: the history, the motivation, the battles, the future – Tony Morris

Не интересно.

Фреймворк Akka и его использование в Яндексе – Вадим Цесько

  • Интересно не сколько про саму akka, там уже некоторые вещи неактуальны для новых версий. Для себя вынес только факт того, что не стоит крутить акторы в системном дефолтном диспечере.
  • Интересно было послушать про систему в общем и узнать, как построена структура обработки данных.
  • Интересно смотреть, как это всё меняется, и меняется ли в связи с akka streams.

CRDTs Illustrated – Arnout Engelen

Хороший начальный обзор CRDT с наглядными схемами.

Propositions as Types – Philip Wadler

  • Известный доклад Вадлера. Стоит посмотреть и посмотреть до конца.
  • Вадлер рассказывает об истории развития теоретической базы под разными концепциями, на которых построены языки программирования.
  • Выжимка: все изобретено дважды. Сначала математиками, потом в computer science.

Learning scalaz – Eugene Yokota

  • Очень поверхностный рассказ про scalaz, скорее про проблемы, которые он может решить.
  • В конце – список полезных книг и их обзор.

Zipkin at Twitter – Jeff Smick

Zipkin – система трассировки логов в распределённых сервисах.

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

Scaling Intelligence: moving ideas forward – Jessica Kerr

Про кривую изучения scala и community вокруг языка. Про то, как должна выглядеть документация и руководства, чтобы они были понятны людям с разными уровнями понимания computer science и математики, присутствующей в scala.

Позиция автора очень релевантна моему представлению о процессе обучения.

Optimising Scala for fun and profit – Rory Graves

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

прокомментировать

Видео со ScalaDays 2015 San Francisco

Заметки к некоторым видео с главной scala конференции. Все видео и слайды давно доступны на сайте parleys.com.

Scala - where it came from, where it's going - Martin Odersky

Key note конференции. Советую всем, кто интересуется будущим scala и взглядом на это Мартина. Упоминали новый компилятор dotty, scala.js, scala 2.12. Кстати да, DSL для XML собираются вынести из языка в строковые интерполяторы.

Akka HTTP: the Reactive Web Toolkit - Roland Kuhn

Про стримы в Akka, с демонстрациями кода. Роланд начинает с соединения TCP со стримами, описывает реализации кастомных протоколов и доходит к тому, как на всём этом реализован HTTP. В ответах на вопросы к докладу упомянуто много планов по развитию стримов и HTTP в akka. Из важного я узнал, что netty внутри play планируют заменить на новый HTTP core.

Reactive Slick for Database Programming - Stefan Zeiger

В начале доклада капитанские вещи о том, какие проблемы есть с БД в асинхронных окружениях и как их принято решать. Затем описывается state и IO монады. Затем объяснятся как slick решает вопросы доступа к БД, представления результатов и зачем там Futures. Интересную мысль, которую я вынес, что при текущей моделе БД асинхронные драйвера, которые стали появляться, не решают проблему, так как внизу БД всё равно работает в синхронном стиле.

Type-level Programming in Scala 101 - Joe Barnes

Весёлая вводная в type-level программирование без углубления в незначительные на первых этапах детали. С примерами кода и тестов. Доклад в режиме ответов на вопросы, которые, к сожалению, не всегда слышно.

Function-Passing Style, A New Model for Asynchronous and Distributed Programming - Heather Miller

Интересный доклад о попытках написать решение, которое в некоторых случаях может использоваться как замена модели акторов. В двух словах идея в том, что стейт может жить в одном месте, а обработка его вызываться из другого, для чего по сети можно передавать лямбды, вместо данных. При этом топология решения может быть любая, как ptp, так и master-slave, например. Если я всё правильно уловил, уже есть работающий прототип.

прокомментировать

Мониторинг CO2 и работа с USB на scala

Озадачился мониторингом CO2 в помещениях. Сначала смотрел на отдельные датчики, думая собрать на коленке и rPi, но потом нашёл дешёвый сборный комплект Masterkit MT8057. Он настолько отличный, что с удовольствием его рекламирую.

В результате у меня получился драйвер к MT8057 на scala и stand alone утилита, ниже в посте поделюсь некоторыми заметками к этой реализации.

Драйвер MT8057

Для MT8057 есть opensource реализация утилиты для съёма параметров от Олега Булатова написанная на C – co2mon. co2mon вариант хороший и рабочий, поддерживает и OS X, и Linux. Наверное, я бы справился докрутить туда выгрузку данных в InfluxDB, куда я собирался сложить все метрики, но решил пописать своих велосипедов, попрактиковаться в низкоуровневых штуках на scala и вспомнить работу с USB.

В первый подход взял хороший и зрелый проект usb4java, но оказалось, что с поддержкой OS X там беда. Требуются извращения типа выгрузки-загрузки kext'ов, которые у меня ещё и не завелись с первого раза.

Во второй подход взял hid4java, этот продукт хоть и анонсируется, как годный к production использованию, ещё достаточно сырой. Шаг влево, шаг вправо и ловишь jvm crash где-то в кишках интеграции с C-шной библиотекой. Написан через JNA, внутри лежат скомпилированные библиотеки для Linux x86_64, Linux ARM, OS X и ещё нескольких платформ. На OS X работает без всяких танцев с kext'ами. Из проблем – API не очень удобный, хуки вызываются из каких попало тредов, у меня это обходится с помощью обёртки с потокобезопасной очередью. Часть методов работает как бы правильно, возвращает правильные Java объекты, но при попытке что-то вызвать у этого объекта получаешь ошибку или crash, так что пришлось добавить костыль.

HID это отдельный класс USB устройств, поэтому не всегда будет выбор между этими библиотеками, в частности usb4java (а вернее libusb) ничего про HID не знает и знать не собирается.

Scala для работы с байтами

В scala всё просто и удобно. Массивы java типа byte[] в Scala превращаются в Array[Byte]. Вооружившись в добавок scala.collection.JavaConversions можно писать привычный scala код.

Внутри драйвера есть зубодробительный код с распаковкой данных от MT8057 и всё это неплохо легло в scala код, местами даже функциональный.

Результат

На выходе у меня получился драйвер MT8057 и декодер к HID пакетам с данными. В отдельный артефакт я их не выделял, но при необходимости это можно сделать.

Про драйвер можно ничего не знать и использовать готовую утилиту ambient7-mt8057-agent которая из зависимостей требует только jre 1.6+ и пока умеет выводить данные в stdout/stderr (для записи в текстовый лог) или работать в интерактивном режиме с ANSI цветами в консоле. На подходе ещё возможность писать в InfluxDB. Готовый jar можно скачать в github.

Про InfluxDB, если удастся с ним подружиться, расскажу отдельно.

прокомментировать

Шаблонизация с handlebars и json4s на scala

Занимаюсь неспешно своим проектом scala.moscow. Одна из задач – примитивный генератор статических сайтов. Очень хотелось чего-то простого для шаблонизации. Думал взять mustache, но оказалось, что это уже не совсем модно-молодёжно, так как есть его расширения handlebars и hogan.

Handlebars мне больше приглянулся. Для scala есть нативная реализация на парсер комбинаторах handlebars.scala и её форк. По фичам scala реализация очень ограничена, в частности, нет встроенной поддержки наследования шаблонов, которая в handlebars делается не силами шаблонизатора, а силами helper'ов. В итоге взял handlebars.java, который выглядит достаточно зрелым и имеет в составе, как минимум, helper'ы partial и block для наследования и i18n.

После выбора шаблонизатора встал вопрос как в него загружать данные. Встроенные резолверы не удобно использовать в scala, да и хотелось чего-то более простого, чем создания пачки классов-контейнеров для данных. А что есть проще для описания примитивных структур данных, чем JSON. Для scala нашёлся отличный DSL для JSON - json4s, у которого в частности есть такой лаконичный DSL:

import org.json4s.JsonDSL._

val data =
    ("copyright" ->
      ("year" -> "2015")
    ) ~
    ("assets" -> ("path" -> "/assets")) ~
    ("title" -> "scala.moscow") ~
      ("main" ->
        ("id" -> "main")
      ) ~
      ("about" ->
        ("id" -> "about") ~
        ("title" -> "scala.moscow :: о проекте")
      )
    )

Плюс к этому handlebars и задумывался для комбинации с JSON, что отражается в его синтаксисе. Плюс к этому сразу решается вопрос, где хранить статические данные, которые не нужно генерить программно – в JSON файлах. В json4s конечно есть не только DSL, но и парсеры на основе нативной scala реализации и jackson.

Чтобы подружить handlebars.java и json4s DSL, написал ValueResolver, идею и часть реализации подсмотрел у handlebars-json4s, но доработал её, решил часть проблем и дописал тестов. Как решу оставшиеся проблемы планирую сделать отдельный артефакт.

прокомментировать

Akka. Тестирование в общем и про тестирование кластера в частности

Продолжая заниматься hello world'ом на akka погрузился в вопрос тестирования акторов.

Общие вещи просты, не вижу смысла пересказывать документацию, остановлюсь только на ключевых моментах и выводах.

Асинхронное vs синхронное тестирование

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

TestProbe и TestActor

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

На деле всё проще. Внутри вашего TestCase создаётся TestProbe и TestActor, которые затем используются для запросов к акторам и анализа приходящих результатов. К сожалению, в документации сразу показывается пример с trait ImplicitSender, который слегка "гримирует" наличие testActor, что вызвало по началу повышенное количество wtf-per-line.

Соответственно набор стандартных assert'ов на самом деле вызывается у стандартного TestProbe. Конечно же таких TestProbe можно даже создать несколько и, например, поместить в них дополнительные специфичные вам assert'ы.

Отсюда же вывод, что для тестирования parent-child взаимодействия придётся вставлять между ними тестовый актор с проксированием сообщений, в документации описаны способы сделать это. В любом случае production код нужно немного к такому подготовить, другой вопрос, что изменения полезны и для других целей.

Cluster testing

С тестированием кластерных конфигурацию всё не так тривиально.

Для начала есть решение multi-jvm тестирования с плагином для sbt, в документации к akka описано как это всё подружить с тестами, чтобы получить Multi Node Testing. Пригодится и для других задач, когда используется просто akka remote.

Печалит, что нужно серьёзно "испортить" конфиг sbt, но, наверное, можно решить выносом таких тестов в отдельный sbt проект. Также ваша IntelliJ IDEA по понятным причинам про такие тесты ничего знать не будет, так как всё магия работает только в связке с sbt. Думаю, в ScalaIDE будет аналогично.

Простого способа дебажить это тоже нет. Логи не очень удобны, так как валяться в параллель со всех JVM. В идеале нужно писать обёртки, которые будут собирать их по каждой ноде отдельно.

"... напоминает мне игру: "Что? Где? Когда?" называется! Непонятно, что где валяется и когда все это кончится!"

Общерекомендуемый подход писать multi-jvm тесты в одном классе, который будет одинаково выполняться на всех нодах. Это обязывает постоянно следить за тем какой код и где исполняется. Например, написанный в лоб assert будет выполнен на всех нодах, часть из которых может быть ещё не присоединена к кластеру.

Постоянно об это спотыкался, но потом написал себе пару удобных утилиток:

import scala.collection.mutable
import org.scalatest.{ BeforeAndAfterAll, Matchers, Suite }
import akka.cluster.Cluster
import akka.cluster.ClusterEvent.{ CurrentClusterState, MemberUp }
import akka.remote.testconductor.RoleName
import akka.remote.testkit.{ MultiNodeSpec, MultiNodeConfig, MultiNodeSpecCallbacks }
import akka.testkit.ImplicitSender



abstract class MultiNodeBaseSpec(config: MultiNodeConfig)
  extends MultiNodeSpec(config)
  with Suite
  with BeforeAndAfterAll
  with MultiNodeSpecCallbacks
  with ImplicitSender
  with Matchers
{

  override def beforeAll() = {
    super.beforeAll()
    multiNodeSpecBeforeAll()
  }

  override def afterAll() = {
    enterBarrier("before-clean-up")
    cleanUp()
    enterBarrier("clean-up")
    multiNodeSpecAfterAll()
    super.afterAll()
  }

  def cluster: Cluster = Cluster(system)
  cluster.subscribe(testActor, classOf[MemberUp])
  expectMsgClass(classOf[CurrentClusterState])
  println(s"myself address: ${node(myself).address}, role: ${myself.name}")

  val currentClusterNodes = mutable.Set[RoleName]()

  def joinToCluster(nodes: Seq[RoleName], seedNode: RoleName): Unit = {
    currentClusterNodes ++= nodes
    // on new nodes await events for all cluster member
    runOn(nodes: _*) {
      cluster join node(seedNode).address
      (receiveN(currentClusterNodes.size).collect { case MemberUp(member) => member.address }.toSet
        should contain theSameElementsAs currentClusterNodes.map(node(_).address).toSet)
    }

    // on existing nodes await events for only new cluster members
    runOn((currentClusterNodes -- nodes.toSet).toList: _*) {
      (receiveN(nodes.size).collect { case MemberUp(member) => member.address }.toSet
        should contain theSameElementsAs nodes.map(node(_).address).toSet)
    }

    enterBarrier("join-"+ nodes.map(_.name).mkString(","))
  }

  def runOnJoinedNodes(a: => Unit): Unit =
    runOn(currentClusterNodes.toList: _*) {
      a
    }

  def cleanUp(): Unit =
    cluster.unsubscribe(testActor)
}

В базовом spec'е выше реализовано:

  • подписывание на события кластера
  • метод joinToCluster для правильного присоединения к кластеру нод
  • метод runOnJoinedNodes для выполнения кода на уже работающих нодах кластера, аналогичный по использованию встроенному runOn

Тестирование сети

Есть встроенная поддержка тестирования транспорта и сети с возможностью эмуляции проблем между нодами (blackhole). При этом я надеюсь как-нибудь попробовать приспособить docker, его API и iptables для данных целей, благо multi-jvm, кажется умеет сам в тестах упаковывать тестовую ноду в jar, раскладывать через ssh+rsync, а затем запускать.

Примеры

Можно глянуть, что получилось у меня. Много полезных примеров я обнаружил в самих исходниках akka и в проекте akka crdt.

Вывод

Тестировать akka, даже в сложных конфигурациях можно и нужно, но tooling ещё требует доработки.

прокомментировать

FPConf 2015 - заметки на полях

article featured image

Побывал на конференции FPConf. Поделюсь своими мыслями, возникшими при прослушивании докладов. Я в основном сидел на втором потоке, где было про scala, UI и пр. Первый поток был преимущественно про Erlang и Haskell.

Организаторы обещали, что будет видео, надеюсь пополнить эту статью ссылкам в будущем.

Upd 09.12.2015: дополнил.

Cамурайский путь молодого scala-программиста, Сергей Лобин, Sputnik.ru

В докладе было мало про scala, больше про проблемы при разработки геокодера в Спутнике. Главный печальный для всех фанатов Scala вывод – Scala в production и них не прижилась, найти разработчиков сложно, Go разработчиков найти значительно проще.

Макросы scala, Михаил Муцянко, JetBrains

Хороший вводный доклад про макросы Scala от разработчика Scala plugin в IDEA.

Из запомнившегося:

Удобный способ построения AST в макросе через Q интерполятор (квазикватирование).

Килер фича, когда Михаил нажатием одной волшебной кнопки прямо в IDEA, показал как разворачивается макрос в Scala код. К сожалению оказалось, что это не из production версии плагина и вроде ожидать такое в ближайшее время не стоит, так как работает не всегда корректно. Очень вкусная возможность, будем ждать.

В 2.12 ожидается значительное улучшение в деле разработки макросов за счёт нового проекта ScalaMeta.

Хорошая ссылка на изучение: What Are Macros Good For? от Евгения Бурмако YouTube, слайды. BTW про самого Евгения и его работу над Scala макросами можно узнать в EaxCast S02E10.

Доклад рекомендую к просмотру.

Встраивание языка в строковой интерполятор, Михаил Лиманский, ЭСК

Хороший практический доклад, как вместо DSL порой можно обойтись интерполятором. Какие возможности, плюсы и минусы такого подхода. Можно прямо брать доклад и писать свой интерполятор как по tutorial'у.

В качестве домашнего задания для себя запомнил задачу реализовать интерполятор для типобезопасного форматирования строки. Хотим с aveic попробовать независимо друг от друга реализовать это и посмотреть, что получиться.

Рекомендую для тех, кто интересуется темой.

Lenses And Prisms, Эдвард Кметт

Самый звёздный докладчик на конференции. К сожалению без знания хотя бы основ синтаксиса Haskell понять что-то было сложно. Докладчик проводил доклад в потрясающей форме - выдавая как из пулемёта кучу кода на Haskell прями в vim'е.

Чтобы понять что к чему, я смотрел на порт этой библиотеки на Scala - Monocle.

В общих словах – это удобный способ изменения иммутабельных структур с возможностью написания максимально абстрактных маленьких кусочков с дальнейшим комбинированием в более сложные кусочки.

Видео к сожалению не выложили.

Реактивные потоки в backend-е, Алексей Романчук, 2ГИС

Хорошая success story про использование akka streams в production. Для меня теперь это один из ответов на вопрос «где нам нужна akka?».

Забавные слайды с цветными "сосиками".

Прозвучавшее число потерь на akka streams по сравнению с голыми акторами ~10%.

Рекомендую всем, кому интересны akka streams.

Scala performance для сомневающихся, Роман Гребенников, Sociohub.ru

Самый запомнившийся доклад. Покрывает сразу две темы - пару примеров того как все модные молодёжные FP штуки из scala отражаются в bytecode JVM и машинном коде, какие потери они за собой несут или не несут. А также способы самому развернуть, померить и понять как выполняется тот или иной код.

Вкратце про проблемы – простой pattern matching по типу параметра - также быстро как колбаса из if'ов. Есть проблемы с boxing/unboxing в Scala collection и прикладывать @specialized не поможет.

Рекомендую к просмотру.

В общем

Очень приятное послевкусие от конференции, не ожидал, что про FP будет так целостно. Как сказали организаторы было 180 человек.

Не посмотрел в живую «Фронтэнд без грусти» Никиты Прокопова, о котором наслышан от коллег, которые видели доклад на какой-то другой конференции. А также хочется поглядеть на «Aрхитектура UI на основе функциональных линз» от Ильи Беда.

Буду ждать видео. Дождались.

прокомментировать