• Deed: a fast encoding and decoding library for Clojure

    Table of Content

    About

    Deed is a library to dump any value into a byte array and read it back. It supports plenty of types out from the box: Java primitives, most of the Clojure types, Java collections, date and time, and so on. It supports even such tricky types as atoms, refs, and input streams. The full list of supported types is shown in the “Supported Types” section below.

    Deed can be extended with custom types with ease. There is a contrib package that extends encoding and decoding logic for vectors from the the well-known mikera/vectorz library.

    Deed is written in pure Java and thus is pretty fast (see the “Benchmarks” section). It’s about 30-50% faster than Nippy.

    It doesn’t rely on the built-in Java Serializable interface for security reasons. Every type is processed manually.

    Deep provides convenient API for reading the frozen data lazily one by one.

    Motivation

    Obviously you would ask why doing this if we already have Nippy? This is what I had in mind while working on Deed:

    1. The library must be absolutely free from dependencies. This is true for the deed-core package: it’s written in pure Java with no dependencies at all. By adding it into a project, you won’t blow up you uberjar, nor you will have troubles with building a native image with GraalVM.

    2. Any part of Deed that requires 3rd-party stuff must be a sub-library. So you have precise control of what you use and what you don’t

    3. Unlike Nippy, Deed never falls back to native Java serialization. There is no such an option. Thus, your application cannot be attacked by someone how has forged a binary dump.

    4. Deed is simple: it blindly works with input- and output byte streams having no idea what’s behind them. It doesn’t take compression nor encryption into account – yet there are utilities for streams.

    5. The library provides API which personally I consider more convenient than Nippi’s. Namely, Deed can lazily iterate on a series of encoded data instead of reading the whole dump at once.

    6. Finally, why not using popular and cross-platform formats like JSON, Message Pack, or YAML? Well, because of poor types support. JSON has only primitive types and collections, and nothing else. Extending it with custom types is always a pain. At the same time, I want my decoded data be as close to the origin data as possible, say, LocalDateTime be an instance of LocalDateTime but not a string or java.util.Date. Sometimes, preserving metadata is crucial. To haldle all of these cases, there now a way other than making your own library.

    Read more →

  • World of Goo 2

    Вышла вторая часть World of Goo. Я долго не знал об этом, потому что повестка забита другим, да и на работе зашиваюсь. Однако это самая приятная новость за последние полгода или около.

    Изюминка в том, что с момента первой части прошло шестнадцать лет. И дело не в том, какая графика или саундтрек в новой части. Просто испытываешь радость за тех двух парней, которые выкатили продолжение. Такое же чувство испытываешь, когда любимая группа записала альбом после долгих лет турне.

    Шестнадцать лет исполнилось моему старшему ребенку. Помню, как начал играть в Гушек, когда ему было пять месяцев. Гушек прошли вдоль и поперек двое моих детей, третьей еще предстоит.

    Если вы не играли в первую часть, горячо советую это сделать. Игра — не просто залипательная казуалка. В ней много попыток что-то донести между строк. Почти каждый уровень — это метафора на что-то из жизни. Попадаются намеки на отношения, красоту и любовь. Есть серия уровней в компьютере, где моделируется перехват трафика, балансировка нагрузки и другие айтишные штучки. Есть длинный диалог на тему браузерных кук. Ближе к концу — эпичный поворот с удаленными электронными письмами.

    Приятно не только расставлять шарики, но и ловить подсказки, намеки, искать отсылки. Гушки — настоящее произведение искусства. Спасибо двум парням, которые заставили часами залипать в этот мир. Прошло шестнадцать лет — и я снова загляну туда, пусть ненадолго, но с тем же интересом.

  • UI и пустота

    Понимаю, что многие не любят подобный контент, но все-таки. На ужасные вещи нужно обращать внимание, что случайно не сделать так же.

    Мне интересно, почему веб превращается в пустыню? На страницах чудовищно много пустоты. Кругом жирные отступы, блоки помещаются в прямоугольники с обводкой, те – в другие прямоугольники и так далее рекурсивно. И всюду отступы, отступы, отступы. Стало нормой, что на первом экране ничего не вмещается – только слои всяких виджетов и жирная блямба посередине. Нужно проматывать ради одной строки.

    Фронтендеры, что же с вами случилось?

  • Мышление лямбдами

    В проекте, который плотно сидит на Амазоне, я познакомился с новой для себя вещью: мышлению лямбдами. Это когда на каждый чих создается лямбда, и кто-то ее вызывает: бекенд, фронтенд, очередь или хук, повешенный на бакет.

    Раньше я об этом не думал, но оказалось, что лямбда — самый сложный продукт Амазона. В экосистеме AWS лямбды повсюду. Их можно приделать к любому сервису. Загрузил файл в S3 — дернулась лямбда. Поднялся инстанс EC2 — дернулась лямбда. Лямбда может быть обработчиком очередей SNS и SQS. Это универсальный клей, которым можно соединить что угодно.

    Лямбда может создана на любой технологии: на Джаве, на Го, на баше. Она может быть голым бинарником или скриптом на Питоне или Ноде. В последних случаях ее код можно поместить прямо в yaml-конфиг Cloud Formation.

    Ситуация, когда лямбда вызывает лямбду, та вызывает лямбду, та вызывает лямбду, которая пишет файл в S3, и на это событие вызывается лямбда, уже не кажется абсурдом. Поначалу шокирует, но привыкаешь.

    Другой случай: как поднять инстанс EC2 на заданное количество времени? А вот как: дернуть лямбду и передать ей число секунд, скажем, 7200 (два часа). Лямбда запустит инстанс из образа, после чего запишет в S3 файл с числом оставшихся секунд. В облаке работает шедулер, который каждые 5 минут запускает другую лямбду. Эта лямбда читает число секунд из бакета, вычитает из него 300 секунд и записывает обратно. Если время истекло, она дергает третью лямбду, которая убивает инстанс. Вот такие многоходовочки.

    Сперва у меня было чувство, словно я рассматриваю картины Сальвадора Дали. Первая реакция — что, так можно было? Оказалось да, можно. С этим живут, это поддерживают, на этом зарабатывают деньги. Такие схемы даже работают. Тех, кто их проектирует, называют AWS-архитекторами.

    Все это я понимаю и принимаю. И все же малодушно хочу, чтобы такого было меньше.

  • Баки

    Со словом “баксы” (доллары) интересная ситуация. Bucks — это уже множественная форма слова buck. Один доллар — один бак. Получается, что два доллара — это два бака. Поэтому вместо “ы” на конце нужно склонять по правилам русского языка.

    То же самое со словом “чиксы”. Дословно chiks означает “цыплята”, и это уже множественная форма. В переносном смысле оно означает девушек, ищущих мужского внимания. По аналогии, если “чикс” — множественная форма, то единственная будет “чик” или “чика”.

    Потренируемся: Алексей показал бумажник, полный баков. За ним увязались модные чики. Все чики любят наличные баки. В Пятерочке сказали, что не принимают баки, только рубли. Чики ушли от Алексея к Михаилу. У него нет баков, зато полно рублей.

    Хм, как-то непривычно.

    Из комментариев в Телеграме: рельсы (рели), чипсы (чипы), джинсы (джины), комиксы (комики).

  • AirDrop

    В интересном мире мы живем. Казалось бы, функция AirDrop не требует интернета, работает автономно за счет локального файфая и блютуза. И все равно — кинуть файл с ноута на мобилу проще через Телеграм. А это, на минуточку, отправка файла бог весть куда, его обработка на сервере, скан на вирусы, индексация меты и загрузка обратно. Приличный такой раунд-трип.

    И все равно это быстрее, чем радиосвязь между двумя устройствами, расстояние между которыми полметра.

    Был же комикс xkcd, где чел говорит: пока ты будешь регистрироваться в Dropbox, я уже с флешкой приеду. С AirDrop что-то из этой оперы: пока он сканит девайсы, Телеграм уже давно прожевал файл.

  • Подорожание Яндекса

    Как вы знаете, Яндекс поднял цену на подписку «Плюс». Это событие обсуждалось на всех площадках. Теперь когда интернет отпустило, выскажусь и я.

    Дело вот в чем: людей взбесил не факт подорожания, а лицемерное письмо, которое разослал Яндекс. Оно и стриггерило пользователей.

    Письмо написано в таком ключе: ребята, мы тут думали-думали, как бы сделать вам хорошо, всю голову сломали. И решили добавить в подписку никому не нужный сервис А и никому не нужный сервис Б.

    И это не все! В сервисе В появилась такая-то фигня, в сервисе Г – такая-то.

    И лишь в третьем абзаце упоминается пустяковая деталь: подписка повышается в два раза, следующее списание тогда-то.

    Читаешь и чувствуешь испанский стыд. Копирайтеры Яндекса действительно считают, что если новость о повышении задвинуть в третий абзац, то ее не заметят. Что клиент Яндекса – однозадачный человек, который держит в голове одну мысль. Если закинуть ему новость про сервисы, то подорожание он проигнорирует.

    Это так глупо и дешево! Словно вернулись на десять лет в прошлое, когда копирайтеры верили в разные техники и манипуляции, чтобы управлять читателем.

    Клиент Яндекса – это городской образованный человек среднего возраста. Ежедневно он читает много сообщений и прекрасно знает эти фокусы. Даже если он не может обозначить их явно, в письме чувствуется фальшь: главное задвинули в конец, а незначительное стоит впереди, чтобы запорошить глаза.

    Каждому, кто прочел это письмо, ясно, что повышение цен и было главной новостью. Ведь так? Кого обманывает Яндекс? Главное должно быть вначале.

    О повышении цен нужно писать явно. Сервисы регулярно поднимают цены, например, тот же Гугл. При этом он не пишет лицемерных писем, не пытается прикрыться новыми сервисами. Все просто: чуваки, через три месяца подписка станет семь долларов вместо пяти. Клиенты такие: ну ок.

    Вот как можно было написать:

    Дорогой Иван, мы повышаем цену на подписку Плюс. Было столько-то, через три месяца станет столько-то. Это необходимо, чтобы поддерживать и развивать продукты Яндекса.

    Чтобы вы не расстраивались, мы добавили никому не нужные сервисы А и Б, а также фичи В и Г в таких-то сервисах. Ссылки на биллинг и прочая информация.

    Словом, Яндекс эпично провалился с этим письмом. Еще не научились копирайтеры Яндекса общаться с аудиторией.

  • Файлы Yaml

    Пару дней назад я славно покувыркался с yaml-файлами.

    Значит, есть два репозитория с плейбуками Ansible. Нужно добавить в каждый файл новую таску. Копирую и вставляю в первый — все в порядке. Копирую во второй, и на CI лезут ошибки парсера.

    Смотрю, а дело вот в чем: в первом файле были отступы в два пробела. В том куске, что я копировал, было тоже два, поэтому он сел без проблем. А во втором файле кто-то использовал четыре пробела. Вставил таску где-то посередине, и пожалуйста: ParserException on line 63, position 15. Тупил над этим десять минут, еще десять минут заняла вторая неудачная итерация, в итоге через полчаса починил.

    Ну и вообще, ямл — он такой ямл. Когда плоская мапа, выглядит красиво, вопросов нет. Но когда у тебя вектор мап векторов мап, это просто ад. Все эти минусики и двоеточия сливаются в общую массу, и если нужно перенести кусок с одного уровня на другой — все, тушите свет. А бородатым девопсам с километрами ямла это нормально: у них ансиблы и кубернетисы всякие.

    Более общая мысль — значимые отступы были ошибкой. Идея, что мы уберем фигурные скобки и заменим пробелами, выглядит красиво только на первый взгляд. За красоту нужно платить — чаще всего, падающими билдами или скрытыми багами, когда мапа уехала не туда.

    Разумеется, вы готовы предъявить: в Питоне отступы и он популярен. Съел? Все равно считаю, что пробелы — это ошибка. Когда я занимался Питоном, у нас были свои кулстори на эту тему. Например, оператор return уехал из-под условия или в критический патч закрался таб — и наложение этого патча положило прод.

    Я как-то уже писал: хорошо, когда форма имеет явные начало и конец. Чтобы не было контекста, в рамках которого нужно гадать, закончилась форма или нет. Для обозначения границ можно взять скобки. И получится…, стойте, это же… о щи-и-и..!

  • Аватарки

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

    Это гнилой пафос. Двадцать лет назад конференции были штучными, и попасть туда можно было только по блату. Сегодня кто угодно может выступить где угодно. Когда я смотрю на аватару выступающего, представляю, как он предлагает перейти на MongoDB или переписать все на Раст. Ну или похожий бред.

    Человек с микрофоном на аватаре напоминает кису с новым айфоном. Глупый китч. Не надо так.

  • Сбой времени (2)

    Кажется, я понял, из-за чего происходит сбой времени на маке. Дело в истощении батареи, которая питает часы на материнке. А вот как она истощилась — это отдельная история.

    У меня два мака: корпоративный для работы и личный для ютубов. Два зарядника, значит. На личном батарея так себе, и ее нужно часто заряжать. Чтобы не таскать зарядник в офис, я сделал так: соединил рабочий мак с личным по Type-C. Поскольку рабочий мак на своем заряднике, он снабжает питанием личный мак. Зарядник для личного лежит дома.

    Хорошая идея, но посыпалось она вот на чем. Оказалось, что когда один мак питается от другого мака, он только питается, а не заряжается. В системном трее появляется иконка с проводом и вилкой, и если навести мышку, будет написано “Power Source: Adapter”. Но ниже — “Battery is not charging” — батарея не заряжается. Ноут как будто становится стационарным компом, который ничего не знает о батарее.

    За неделю батарея истощилась под ноль, хотя внешне это никак не сказывалось. Когда я отцепил мак от Type-C, он тут же умер. А после тяжелой перезагрузки полезли глюки со временем. Удаление базы с таймзонами и несколько циклов заряда не помогли.

    Получается вот что: можешь работать от провода, но наполнения батареи не будет. Тим Кук не одобряет, что на два мака приходится одна зарядка. Не порядок. Хочешь или нет, понадобится вторая. В качестве побочки — убитая батарейка, которая питает время.

    Посмотрим, подтвердят ли мою догадку в ремонте.

    UPD: в комментариях в Телеграме пишут, что бывают зарядки с двумя Type-C портами. Увы, они расчитаны только для мощного и слабого устройств одновременно, например макбука и телефона. Два мака одновременно они не тянут.

Страница 2 из 84