• PG docs, part 5. Notifications

    (This is a new documentation chapter from the PG project.)

    ToC

    Notifications

    Introduction

    Notifications are somewhat pub-sub message systems in Postgres. They can be described in these simple steps:

    • client B subscribes to a channel; the channel gets created if it doesn’t exist.

    • client A sends a message to that channel;

    • every time client B interacts with the database, they receive messages sent to this channel by other clients.

    To handle a message, the client invokes a special handler. This handler comes from the configuration. The default handler just prints the notification map. Pay attention that the handler is called synchronously blocking the interaction with a socket. To prevent the connection from hanging due to the time-consuming handling of a notification, provide a handler that sends it to some sort of channel, agent, or message queue system.

    Read more →

  • PG docs, part 4. Arrays

    (This is a new documentation chapter from the PG project.)

    ToC

    In JDBC, arrays have always been a pain. Every time you want to pass an array to the database or read it back, you’ve got to wrap your data with various Java classes, extend protocols, and multimethods. We do it in each project, and it doesn’t have to be like this.

    The recent release of PG ships a significant feature: arrays. You can pass an array to a query and read it back as easily as they were native Clojure vectors. No more ceremonies with classes, manual parsing, etc.

    Read more →

  • PG docs, part 3

    (This is a new documentation chapter from the PG project.)

    ToC

    Connection Pool

    To interact with a database effectively, you need a connection pool. A single connection is fragile on its own: you can easily lose it by an accidental lag in the network.

    Another thing that is worth bearing in mind is, that opening a new connection every time you want to reach PostgreSQL is expensive. Every connection starts a new process on the server. If your code opens too many connections, say in a cycle or within threads/futures, sooner or later you’ll reach an error response saying “too many connections”.

    The connection pool is an object that holds several open connections at once. It allows you to borrow a connection for some period of time. A borrowed connection can be only used in a block of code that has borrowed it but nowhere else. Once the block of code has done with its duties, the connection gets returned to the pool.

    The pool is also capable of calculating the lifetime of connections and their expiration moments. Once a connection has expired, it gets terminated and the pool spawns a new connection.

    The connection pool is shipped in a dedicated library com.github.igrishaev/pg-pool as it depends on the logging facility.

    Read more →

  • PG docs, part 2

    ToC

    In this chapter, we’ll discuss how to reach Postgres using the Client library.

    Basic usage

    Here is a brief example of using the client library:

    (ns scratch
      (:require
       [pg.client :as pg]))
    
    (def config
      {:host "127.0.0.1"
       :port 5432
       :user "test"
       :password "test"
       :database "test"})
    
    (pg/with-connection [conn config]
      (pg/query conn "select 1 as one"))
    
    ;; [{:one 1}]
    

    First, you import the pg.client namespace which brings the top-level API functions to interact with Postgres. The config map above specifies the minimal configuration; it might have more fields which we will explore in a separate section.

    The with-connection macro establishes a new connection, binds it to the conn symbol, and executes the body. The connection is closed afterward, even if an exception pops up.

    Technically you can open and terminate a connection manually like this:

    (let [conn (pg/connect config)
          data (pg/query conn "select 1 as one")]
      (pg/terminate conn)
      data)
    
    ;; [{:one 1}]
    

    but it’s not recommended. Also, since the Connection object implements java.io.Closeable, it’s possible to use it in with-open:

    (with-open [conn (pg/connect config)]
      (pg/query conn "select 1 as one"))
    
    ;; [{:one 1}]
    

    Read more →

  • PG docs, part 1

    TL;DR: I’m writing a Postgres driver in pure Clojure. In general, works! Now I proceed with the most miserable part of the project: writing documentation. I decided to do it step by step and share it on my blog.

    ToC

    About

    This project is a set of libraries related to the PostgreSQL database. The primary library called pg-client is a driver for Postgres written in pure Clojure. By purity I mean, neither JDBC nor any other third-party Java libraries are involved. Everything is driven by a TCP socket and implementation of the Posrgres Wire protocol. Fun!

    Besides the client, the project provides such various additions as a connection pool (see pg-pool). The pg-types library holds the encoding and decoding logic which determines how to write and read Clojure data from and into the database. You can use this library separately in pair with JDBC.next and COPY for efficient data transcoding in binary format.

    The question you would probably ask is, why would create a Postgres client from scratch? JDBC has been around for decades, and there are also good clojure.java.jdbc and jdbc.next wrappers on top of it?

    The answer is: that although these two libraries are amazing, they don’t disclose all Postgres features. JDBC is an abstraction whose main goal is to satisfy all the DB engines. A general library that works with MS SQL, MySQL, and Postgres at the same time would reduce the variety of features each backend is capable of.

    Read more →

  • Анонс второй книги

    Вышел второй том “Сlojure на производстве” — продолжение первой книги. Без той помпы, что в прошлый раз, когда я каждую неделю выкладывал апдейты, фото черновиков и прочее. На всё это не хватает времени, плюс хочется меньше пафоса.

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

    Книжка выполнена в том же стиле и манере повествования. Текст чередуется с кодом, каждый тезис подтверждается примером. Длинный код разбит на части с пояснением, что происходит. Код “подсвечен” с помощью градаций серого и начертания. Ссылки, коих много по тексту, вынесены в QR-коды на поля.

    Твёрдая обложка, B5, 364 страницы. Форматы для мобильных устройств появятся позже. Издано в ДМК-Пресс тиражом в 100 экземпляров. Двадцать из них — мои, полученные в качестве гонорара, и я готов разослать их читателям.

    Все подробности – где купить, открывок, галерея – указаны на странице книги.

  • Node.js

    Удивляюсь, до чего же хрупок этот Node.js. Месяц назад я делал фронт на Vue, и настало время кое-что поправить. Обновляю пакеты, запускаю билд — сотня ошибок. Мудрил так и сяк, пока коллега не сказал — удали node_modules и все заработает.

    Вот это “удали” меня поражает. Вместо того, чтобы решить корень проблемы, решают симптомы. Подумаешь не работает! Просто начни с чистого листа. Ситуация КРИЧИТ о системной проблеме, но никому нет дела. В платформу вливают огромные деньги, ей пользуются миллионы, и никто не может это починить.

    Была б моя воля, я бы посадил разработчиков Node.js за компы и сказал: чини, но без удаления файлов. Найди источник проблемы и реши его. За удаление — пытка током на месте. И тогда бы все починили.

    Помню, была та же беда в проекте с React Native, только хуже. Проект перестал собираться, и я по привычке удалил node_modules. Оказалось, в его недрах лежат бинарники для устройства, которые генерируется на старте. При повторной установке этот шаг пропускается, и где взять эти бинарники — неизвестно. На StackOverflow так и пишут — перед удалением скопируй такие-то файлы в папочку, иначе будешь плакать. Плакал я, конечно, уже после того, как это прочел.

    Вы, наверное, подумали, что после удаления node_modules все заработало? Это было бы слишком просто. Я получил другие непонятные ошибки, и коллега предположил, что моя версия Node.js слишком высока. Проверили — да, у него 16, у меня 20. Но ведь месяц назад все работало на версии 20! Мало того, что за месяц случились такие изменения, так эти клоуны не оставили обратную совместимость! Не иначе как цирком с клоунами эту ситуацию назвать нельзя.

    В целом Node.js вызывает ощущение, что убираешь какашки за годовалым ребенком. Те, у кого есть дети, знают, о чем я говорю. Когда делаешь это постоянно, ощущения притупляются, и можно спокойно чистить говно, жуя бутерброд. Разница в том, что к двум годам проблема с туалетом уходит, а с семи лет ребенок уже поддерживает чистоту сам.

    Node.js, напротив, обречен срать под себя как инвалид. Если через восемь лет за ним нужно чистить какие-то папки, то, похоже, проблема не уйдет никогда. Бог с ним, пусть живет как хочет. Но непонятно, зачем с этим работать, и что в голове у людей, которые добровольно идут в разработку на Node.js.

  • Платежные системы

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

    Конечно, недоступна временно. Подпишись и мы пришлем уведомление. Уже вот-вот, буквально завтра.

    Удалить аккаунт? Не можем: по такому-то закону данные хранятся пять лет, чтобы выдать по требованию властей.

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

    Регистрируясь в похожих системах, сперва нужно гуглить по словам “Service in Country limitations”.

  • Косплей

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

    Если нравится Стив Джобс, сделай Айфон. Если Павел Дуров — сделай соцсеть с той стеной, которую считаешь нужной. Если Лапенко — сними смешной ролик. Но не повторяй внешность или стиль общения в интернете. Это ужасно.

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

    Между великими людьми вообще нет связи. Все они были молодыми и старыми, сатанистами и христианами, бабниками и девственниками. Связи нет никакой. Когда кто-то читает десять правил знаменитости, я не понимаю — зачем? Ведь известность из них не следует.

    Доводилось видеть человека, который косплеил Дурова: челка, плащ до колен, все черное, взгляд мимо камеры. Он делал стартап, и было забавно видеть его за работой. Не знаю, чем кончилась его затея, но судя по всему — ничем.

    Все это сказано цитатой о Стиве Джобсе. У Стива были две половины: одна — редкостный засранец, вторая — редкостный гений. Из-за второй половины ему прощали первую. Сегодня много людей косят под Стива, но у них получается первая половина — засранца.

    Начинайте со второй половины.

  • Как в X

    Совершенно ужасная вещь — писать на яыке X как в Y. Например, в Питоне как на Хаскеле, а в JavaScript — как в Кложе. Придумать какие-нибудь “элегантные объекты” и тыкать людям, что они живут неправильно.

    Чемпионом в этой области является Питон. Из-за его гибкости на нем можно косплеить любой язык — хоть Хаскел, хоть Кобол. Скажем, выражение ниже можно сделать рабочим:

    items = List[1, ...]
    

    Для этого пишут особый класс List с метаклассом, у которого реализован метод __getitem__. В нем проверяется, что если второй элемент — класс Ellipsis, то возвращается ленивый список от 1 до бесконечности.

    Для Питона созданы сотни библиотек, которые косплеят другие языки — Хаскель, Скалу и другие. Я тоже отметился: написал либу с лаконичным названием f, где собраны плюшки Кложи: стрелочные операторы, мультиметоды и всякие мелочи.

    Все это замечательно, если бы не одна деталь: оно никому не сдалось. До перехода в Кложу я работал с Питоном семь лет и ни разу не видел, чтобы использовались функциональные поделки. Промышленные проекты на Питоне — это скучный ООП-код без map/reduce, монад и алгебраических типов. В точности так, как это видит создатель языка.

    Точно так же в Кложе никто не использует монады. Уже в седьмой раз я устраиваюсь кложуристом и не вижу их в проде (и это хорошо).

    В текущем проекте на Кложе беда — его начинали люди, которые знали ее синтаксис, но не идиомы. Другими словами, они знали, что вместо 1 + 2 надо писать (+ 1 2), но не знали, как устроить работу с базой, компоненты, тесты и окружение.

    Кажется, это были рубисты. Я не держал свечку, но это сквозит в коде. Чуваки написали свою ORM, которая матчит базу с REST — кривую и глючную. Для конфигурации используют переменные среды, и это тоже треш и содомия. Компоненты и система убоги. Позже в фирму пришли люди опытом на Кложе. Они либо обходят легаси — ходят в базу напрямую, используют свои решения, — либо прибегают к нему с легким отвращением.

    Идиома “писать на X как в Y” — это проигрыш по определению. В любом виде. Это билет в один конец, и он всегда одинаков. Вы пишете “как надо”, но потом уходите, и другие с трудом приводят код в нужное русло. Не всегда удается сделать это полностью — иной раз авгиевы конюшни столь полны, что переделывать слишком дорого, и с этим как-то живут.

    Легковестные агенты из Эрланга в Кложе. Элегантные объекты в Джаве. Монады вместо исключений в Питоне. Да, интересно, да, ярко. Но бесполезно.

    Если идеи по-настоящему сильны, их нужно выразить в новом языке. Не устраивает чистый C — появляется C++. Не устраивают древние диалекты Лиспа — появляется Кложа. Не нравится бородатый Эрланг — пишут Эликсир.

    На любом языке надо писать так, как в нем принято. На Руби — как в Руби, а не в Кложе. На Кложе — как принято в Кложе, а не в Руби.

    Чем раньше это поймешь, тем скорее на тебя снизойдет благодать.

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