<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ilya Bylich - Blog</title><link>https://iliabylich.github.io/</link><description>Recent content on Ilya Bylich - Blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 19 Mar 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://iliabylich.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>Ruby, Ractors, and Lock-Free Data Structures</title><link>https://iliabylich.github.io/ruby-ractors-and-lock-free-data-structures/</link><pubDate>Wed, 19 Mar 2025 00:00:00 +0000</pubDate><guid>https://iliabylich.github.io/ruby-ractors-and-lock-free-data-structures/</guid><description/></item><item><title>Arena-based parsers</title><link>https://iliabylich.github.io/arena-based-parsers</link><pubDate>Thu, 09 May 2024 00:00:00 +0000</pubDate><guid>https://iliabylich.github.io/arena-based-parsers</guid><description/></item><item><title>Writing bindings upside down</title><link>/2021-12-28-writing-bindings-upside-down/</link><pubDate>Tue, 28 Dec 2021 00:00:00 +0000</pubDate><guid>/2021-12-28-writing-bindings-upside-down/</guid><description>&lt;h1 id="bindings" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 Bindings
 &lt;a href="#bindings"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Quite a long time ago I started writing C/C++/Ruby/Node.js/WASM bindings so I could call &lt;a class="text-blue-500 hover:underline" href="https://github.com/lib-ruby-parser/lib-ruby-parser" target="_blank"
 rel="noreferrer nofollow"&gt;my Rust project&lt;/a&gt;
 from those languages. It is a Ruby language parser.&lt;/p&gt;
&lt;p&gt;I tried multiple ways and found one that is very (VERY) controversial, but I think it deserves it&amp;rsquo;s own article.&lt;/p&gt;


&lt;h1 id="traditional-way" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 Traditional way
 &lt;a href="#traditional-way"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Let&amp;rsquo;s say you have a library in C. Just for simplicity, Rust is not special here.&lt;/p&gt;</description></item><item><title>lib-ruby-parser</title><link>/2020-11-23-lib-ruby-parser/</link><pubDate>Mon, 23 Nov 2020 00:00:00 +0000</pubDate><guid>/2020-11-23-lib-ruby-parser/</guid><description>&lt;h1 id="intro" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 Intro
 &lt;a href="#intro"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;So, I&amp;rsquo;m ready to announce that I have finished working on a new Ruby parser. It&amp;rsquo;s called &lt;code&gt;lib-ruby-parser&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Key features:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It&amp;rsquo;s fast. It&amp;rsquo;s written in Rust and it&amp;rsquo;s slightly faster than Ripper. The difference is about 1-2% on my machine.&lt;/li&gt;
&lt;li&gt;It has a beautiful interface. Every single node has its own type that is documented. For example, take a look at &lt;a class="text-blue-500 hover:underline" href="https://docs.rs/lib-ruby-parser/0.7.0/lib_ruby_parser/nodes/struct.CSend.html" target="_blank"
 rel="noreferrer nofollow"&gt;&lt;code&gt;CSend&lt;/code&gt; node&lt;/a&gt;
 that represents &amp;ldquo;conditional send&amp;rdquo; like &lt;code&gt;foo&amp;amp;.bar&lt;/code&gt;. &lt;a class="text-blue-500 hover:underline" href="https://docs.rs/lib-ruby-parser/0.7.0/lib_ruby_parser/nodes/index.html" target="_blank"
 rel="noreferrer nofollow"&gt;Here&amp;rsquo;s a list of all defined nodes&lt;/a&gt;
. Both Ripper and &lt;code&gt;RubyVM::AST&lt;/code&gt; have no documentation of their AST format. &lt;code&gt;whitequark/parser&lt;/code&gt; &lt;a class="text-blue-500 hover:underline" href="https://github.com/whitequark/parser/blob/master/doc/AST_FORMAT.md" target="_blank"
 rel="noreferrer nofollow"&gt;has a great documentation&lt;/a&gt;
, but its AST is not &amp;ldquo;static&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;What&amp;rsquo;s &amp;ldquo;static AST&amp;rdquo;? By saying that I mean that if documentation says that &amp;ldquo;N is not-nullable&amp;rdquo; then it&amp;rsquo;s true no matter what. &lt;code&gt;whitequark/parser&lt;/code&gt; does a great job, but the nature of dynamic language does not allow it to provide such guarantees. I&amp;rsquo;ll show a few examples later.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s precise. Unlike &lt;code&gt;whitequark/parser&lt;/code&gt;, its lexer (or tokenizer if it sounds better for you) is based on MRI&amp;rsquo;s &lt;code&gt;parse.y&lt;/code&gt;. What does it mean? It means that I was not able to find any difference in tokenizing on 3 million lines of code that I have got by pulling sources of top 300 gems (by total downloads). I&amp;rsquo;ll mention how I track it soon.&lt;/li&gt;
&lt;li&gt;It does not depend on Ruby. In fact, it has absolutely no &amp;ldquo;required&amp;rdquo; dependencies (only a few optional ones). So, it&amp;rsquo;s possible to write bindings for any other language, and I have made them for C/C++/Node.js. Of course, it&amp;rsquo;s possible to have bindings for Ruby (because there are bindings for C and it&amp;rsquo;s easy to reuse them)&lt;/li&gt;
&lt;/ol&gt;


&lt;h1 id="implementation" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 Implementation
 &lt;a href="#implementation"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Current performance (in release mode, with &lt;code&gt;jemalloc&lt;/code&gt;) is ~200000 LOC/s. I think it can even be used for syntax highlighting (and in the browser, too, haha).&lt;/p&gt;</description></item><item><title>Evaluating Ruby in Ruby</title><link>/2020-01-26-evaluating-ruby-in-ruby/</link><pubDate>Sun, 26 Jan 2020 00:00:00 +0000</pubDate><guid>/2020-01-26-evaluating-ruby-in-ruby/</guid><description>&lt;h1 id="tldr" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 TL;DR
 &lt;a href="#tldr"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;This article is about instruction sequences and evaluating them using pure Ruby.&lt;/p&gt;
&lt;p&gt;The repository is available &lt;a class="text-blue-500 hover:underline" href="https://github.com/iliabylich/my.rb" target="_blank"
 rel="noreferrer nofollow"&gt;here&lt;/a&gt;
.&lt;/p&gt;
&lt;blockquote class="border-l-4 border-blue-200 pl-2"&gt;
 &lt;p&gt;Is it a Ruby implementation?&lt;/p&gt;

&lt;/blockquote&gt;
&lt;p&gt;No. It&amp;rsquo;s just a runner of instructions. It is similar to MRI&amp;rsquo;s virtual machine, but it lacks many features and it&amp;rsquo;s 100 times slower.&lt;/p&gt;
&lt;blockquote class="border-l-4 border-blue-200 pl-2"&gt;
 &lt;p&gt;Can I use it in my applications?&lt;/p&gt;

&lt;/blockquote&gt;
&lt;p&gt;Of course, no. Well, if you want.&lt;/p&gt;</description></item><item><title>My favorite parts of Ruby</title><link>/2018-07-19-my-favorite-parts-of-ruby/</link><pubDate>Thu, 19 Jul 2018 00:00:00 +0000</pubDate><guid>/2018-07-19-my-favorite-parts-of-ruby/</guid><description>&lt;h1 id="before-we-start" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 Before we start
 &lt;a href="#before-we-start"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer #1&lt;/strong&gt; first of all I&amp;rsquo;d like to say that I really like Ruby. I write a ton of Ruby code every single day and I prefer it over other languages. Please, do not take it seriously, Ruby is nice, and this post is mostly a joke.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer #2&lt;/strong&gt; I&amp;rsquo;m not going to cover popular things like flip-flops (thanks God they are deprecated in 2.6.0).&lt;/p&gt;</description></item><item><title>Ruby Marshalling from A to Z</title><link>/2016-01-26-ruby-marshalling-from-a-to-z/</link><pubDate>Tue, 26 Jan 2016 00:00:00 +0000</pubDate><guid>/2016-01-26-ruby-marshalling-from-a-to-z/</guid><description>&lt;h1 id="what-is-marshalling" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 What is Marshalling
 &lt;a href="#what-is-marshalling"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Marshalling is a serialization process when you convert an object to a binary string.
Ruby has a standard class &lt;code&gt;Marshal&lt;/code&gt; that does all the job for serialization and deserialization.
To serialize an object, use &lt;code&gt;Marshal.dump&lt;/code&gt;, to deserialize - &lt;code&gt;Marshal.load&lt;/code&gt; or &lt;code&gt;Marshal.restore&lt;/code&gt;.&lt;/p&gt;

&lt;div class="group relative"&gt;
 &lt;button class="hidden group-hover:inline absolute top-0.5 right-0.5 bg-gray-200 p-2 hover:bg-gray-400"
 data-copy="true"&gt;copy&lt;/button&gt;
 &lt;pre class="bg-neutral-800 text-white p-4"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;marshalled &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Marshal&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dump(&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;Object&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;new&lt;span style="color:#f92672"&gt;]&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# =&amp;gt; &amp;#34;\x04\b[\ti\x06i\aI\&amp;#34;\vstring\x06:\x06ETo:\vObject\x00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Marshal&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;load(marshalled)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# =&amp;gt; [1, 2, &amp;#34;string&amp;#34;, #&amp;lt;Object:0x00000002643000&amp;gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This article explains the format of marshalling and shows how to write a pure Ruby marshalling library
compatible with the standard Ruby implementation.&lt;/p&gt;</description></item><item><title>HandlerSocket + Ruby</title><link>/2015-11-10-handlersocket-with-ruby/</link><pubDate>Tue, 10 Nov 2015 00:00:00 +0000</pubDate><guid>/2015-11-10-handlersocket-with-ruby/</guid><description>&lt;h1 id="what-is-handlersocket-hs" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 What is HandlerSocket (HS)
 &lt;a href="#what-is-handlersocket-hs"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;a plugin for MySQL&lt;/li&gt;
&lt;li&gt;which allows you to read/write to MySQL&lt;/li&gt;
&lt;li&gt;and gives you a separate connection to MySQL&lt;/li&gt;
&lt;li&gt;and does not allow you to run SQL queries&lt;/li&gt;
&lt;li&gt;but allows to run simple CRUD queries &lt;em&gt;only&lt;/em&gt; using indexes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HandlerSocket query language is very simple (I&amp;rsquo;d even say it&amp;rsquo;s primitive), but it&amp;rsquo;s much faster than MySQL&amp;rsquo;s one. Though, of course, there are some limitations. Interested?&lt;/p&gt;</description></item><item><title>Saving execution context for later debugging</title><link>/2015-08-21-saving-execution-context-for-later-debugging/</link><pubDate>Fri, 21 Aug 2015 00:00:00 +0000</pubDate><guid>/2015-08-21-saving-execution-context-for-later-debugging/</guid><description>&lt;h1 id="the-problem" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 The problem
 &lt;a href="#the-problem"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Consider the following situation: you have got an exception in production. Of course, all of us are good developers, but you know, sometimes *it just happens. What do you usually do to get some information about the error? You just grab the request parameters to test it locally, right? Then I might have a better solution for you: dump your memory once an error happens and restore the dump later to debug it.&lt;/p&gt;</description></item><item><title>Wrapping JavaScript library with Opal</title><link>/2015-07-23-wrapping-javascript-library-with-opal/</link><pubDate>Thu, 23 Jul 2015 00:00:00 +0000</pubDate><guid>/2015-07-23-wrapping-javascript-library-with-opal/</guid><description>&lt;h1 id="introduction" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 Introduction
 &lt;a href="#introduction"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;The task that is solved here is not real, but it&amp;rsquo;s still a good example of (probably?) real work with Opal. I could choose some complex enough JavaScript library and write a simple wrapper using Opal, but there&amp;rsquo;s no fun. Instead, let&amp;rsquo;s write a wrapper for existing rich client-side application (it may show you how to wrap your existing application logic). Well, wrapper for something like a client-side scheduler may sound boring, so I have chosen a JavaScript-based browser game called &lt;a class="text-blue-500 hover:underline" href="http://browserquest.mozilla.org" target="_blank"
 rel="noreferrer nofollow"&gt;&lt;code&gt;BrowserQuest&lt;/code&gt;&lt;/a&gt;
 &lt;a class="text-blue-500 hover:underline" href="https://github.com/mozilla/BrowserQuest" target="_blank"
 rel="noreferrer nofollow"&gt;written&lt;/a&gt;
 by Mozilla, and I&amp;rsquo;ll show you how to write a bot for it using Opal.&lt;/p&gt;</description></item><item><title>Capybara and asynchronous stuff</title><link>/2015-07-01-capybara-and-asynchronous-stuff/</link><pubDate>Wed, 01 Jul 2015 00:00:00 +0000</pubDate><guid>/2015-07-01-capybara-and-asynchronous-stuff/</guid><description>&lt;h1 id="what-is-capybara-poltergeist-and-phantomjs" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 What is Capybara, Poltergeist and PhantomJS?
 &lt;a href="#what-is-capybara-poltergeist-and-phantomjs"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;In this part I will try to cover the following aspects:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Running asynchronous code in a web driver&lt;/li&gt;
&lt;li&gt;Making the call synchronous&lt;/li&gt;
&lt;li&gt;Wrapping it into some common solution&lt;/li&gt;
&lt;li&gt;Advanced example - working with IndexedDB from Capybara&lt;/li&gt;
&lt;/ol&gt;


&lt;h2 id="phantomjs" class="text-2xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 PhantomJS
 &lt;a href="#phantomjs"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First of all, we need to know what is PhantomJS. I would say it&amp;rsquo;s a &amp;rsquo;tool that acts like a browser but can be controlled from outside using simple command interface&amp;rsquo;. In more common words, it&amp;rsquo;s a web driver. It&amp;rsquo;s a full-featured WebKit (an engine of Chrome/Safari/few last versions of Opera and other browsers), but in console. You can use it for scripting, automating or testing.&lt;/p&gt;</description></item><item><title>Apipie - amazing tool for documenting your Rails API</title><link>/2015-06-08-apipie-amazing-tool-for-documenting-your-rails-api/</link><pubDate>Mon, 08 Jun 2015 00:00:00 +0000</pubDate><guid>/2015-06-08-apipie-amazing-tool-for-documenting-your-rails-api/</guid><description>&lt;h1 id="apipie" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 Apipie
 &lt;a href="#apipie"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;This article is about &lt;a class="text-blue-500 hover:underline" href="https://github.com/Apipie/apipie-rails" target="_blank"
 rel="noreferrer nofollow"&gt;Apipie gem&lt;/a&gt;
 which provides a DSL for documenting your API. I will try to cover features that I personally use on my project.&lt;/p&gt;
&lt;p&gt;Comparing to other tools for generating API documentation (&lt;code&gt;yardoc&lt;/code&gt;, &lt;code&gt;sdoc&lt;/code&gt;) I would say that the main thing that you gain with Apipie is that your documentation is a real ruby code, so you can write computations, concerns etc.&lt;/p&gt;</description></item><item><title>What is Ruby DSL</title><link>/2015-05-26-what-is-ruby-dsl/</link><pubDate>Tue, 26 May 2015 00:00:00 +0000</pubDate><guid>/2015-05-26-what-is-ruby-dsl/</guid><description>&lt;h1 id="what-is-ruby-dsl" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 What is Ruby DSL?
 &lt;a href="#what-is-ruby-dsl"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;As you already know, DSL means domain-specific language. It&amp;rsquo;s like a language in a language. Here are some examples that we use every day:&lt;/p&gt;

&lt;div class="group relative"&gt;
 &lt;button class="hidden group-hover:inline absolute top-0.5 right-0.5 bg-gray-200 p-2 hover:bg-gray-400"
 data-copy="true"&gt;copy&lt;/button&gt;
 &lt;pre class="bg-neutral-800 text-white p-4"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;attr_reader&lt;/span&gt; &lt;span style="color:#e6db74"&gt;:name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Profile&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ActiveRecord&lt;/span&gt;&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Base&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; has_many &lt;span style="color:#e6db74"&gt;:posts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ApiController&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ActionController&lt;/span&gt;&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Base&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; before_action &lt;span style="color:#e6db74"&gt;:authenticate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But all these examples use rails-provided DSL, how about your own? First of all, you should know that all these methods (&lt;code&gt;attr_reader&lt;/code&gt;, &lt;code&gt;has_many&lt;/code&gt; and &lt;code&gt;before_action&lt;/code&gt;) are actually class-methods of &lt;code&gt;Module&lt;/code&gt;, &lt;code&gt;ActiveRecord::Base&lt;/code&gt; and &lt;code&gt;ActionController::Base&lt;/code&gt;. So you can write something like:&lt;/p&gt;</description></item><item><title>Experimental MySQL HTTP API and Ruby</title><link>/2015-05-14-experimental-mysql-http-api-and-ruby/</link><pubDate>Thu, 14 May 2015 00:00:00 +0000</pubDate><guid>/2015-05-14-experimental-mysql-http-api-and-ruby/</guid><description>&lt;h1 id="http-api" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 HTTP API
 &lt;a href="#http-api"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Yes, MySQL has an HTTP API which is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;an experimental feature&lt;/li&gt;
&lt;li&gt;it ships as a native plugin &lt;a class="text-blue-500 hover:underline" href="http://labs.mysql.com/?id=3" target="_blank"
 rel="noreferrer nofollow"&gt;only for 5.7 version&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Basically, it allows you to work with your database in the following ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;as an SQL endpoint&lt;/li&gt;
&lt;li&gt;as a CRUD endpoint&lt;/li&gt;
&lt;li&gt;as a JSON document endpoint&lt;/li&gt;
&lt;/ol&gt;


&lt;h1 id="sql-endpoint" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 SQL endpoint
 &lt;a href="#sql-endpoint"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;It gives an ability to run queries like&lt;/p&gt;</description></item><item><title>ExceptionManager gem</title><link>/2015-04-14-exception-manager-gem/</link><pubDate>Tue, 14 Apr 2015 00:00:00 +0000</pubDate><guid>/2015-04-14-exception-manager-gem/</guid><description>&lt;h1 id="what-is-this" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 What is this?
 &lt;a href="#what-is-this"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;ExceptionManager&lt;/code&gt; is a gem for getting extra information from your exception.&lt;/p&gt;
&lt;p&gt;Source code: &lt;a class="text-blue-500 hover:underline" href="https://github.com/iliabylich/exception_manager" target="_blank"
 rel="noreferrer nofollow"&gt;https://github.com/iliabylich/exception_manager&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;With this gem every time when you get an exception, it&amp;rsquo;s possible to grab &lt;code&gt;subject&lt;/code&gt; of exception (the instance of class where &lt;code&gt;raise&lt;/code&gt; happened), &lt;code&gt;locals&lt;/code&gt; - local variables, &lt;code&gt;subject_instance_variables&lt;/code&gt; and &lt;code&gt;subject_class_variables&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;

&lt;div class="group relative"&gt;
 &lt;button class="hidden group-hover:inline absolute top-0.5 right-0.5 bg-gray-200 p-2 hover:bg-gray-400"
 data-copy="true"&gt;copy&lt;/button&gt;
 &lt;pre class="bg-neutral-800 text-white p-4"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;require &lt;span style="color:#e6db74"&gt;&amp;#39;exception_manager&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;ExceptionManager&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;enable!
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TestClassThatRaisesException&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; @@class_variable &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;:class_value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test_error&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;args)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; @instance_variable &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;:instance_value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;raise&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Test error&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;TestClassThatRaisesException&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;new&lt;span style="color:#f92672"&gt;.&lt;/span&gt;test_error(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;rescue&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; e
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; puts &lt;span style="color:#e6db74"&gt;&amp;#34;Subject: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;#{&lt;/span&gt;e&lt;span style="color:#f92672"&gt;.&lt;/span&gt;subject&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; puts &lt;span style="color:#e6db74"&gt;&amp;#34;Locals: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;#{&lt;/span&gt;e&lt;span style="color:#f92672"&gt;.&lt;/span&gt;locals&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; puts &lt;span style="color:#e6db74"&gt;&amp;#34;Instance variables: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;#{&lt;/span&gt;e&lt;span style="color:#f92672"&gt;.&lt;/span&gt;subject_instance_variables&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; puts &lt;span style="color:#e6db74"&gt;&amp;#34;Class variables: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;#{&lt;/span&gt;e&lt;span style="color:#f92672"&gt;.&lt;/span&gt;subject_class_variables&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; puts &lt;span style="color:#e6db74"&gt;&amp;#34;Summary: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;#{&lt;/span&gt;e&lt;span style="color:#f92672"&gt;.&lt;/span&gt;summary&lt;span style="color:#f92672"&gt;.&lt;/span&gt;inspect&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This code snippet prints:&lt;/p&gt;</description></item><item><title>Redis Cluster. Quick overview.</title><link>/2015-04-13-redis-cluster-quick-overview/</link><pubDate>Mon, 13 Apr 2015 00:00:00 +0000</pubDate><guid>/2015-04-13-redis-cluster-quick-overview/</guid><description>&lt;p&gt;Today I have tested version 3.0.0 of Redis server which includes Redis cluster. Here are some first thoughts about this.&lt;/p&gt;


&lt;h1 id="setup" class="text-4xl border-b-2 mt-8 mb-2 border-black dark:border-gray-400"&gt;
 Setup
 &lt;a href="#setup"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Here are my servers:&lt;/p&gt;

&lt;div class="group relative"&gt;
 &lt;button class="hidden group-hover:inline absolute top-0.5 right-0.5 bg-gray-200 p-2 hover:bg-gray-400"
 data-copy="true"&gt;copy&lt;/button&gt;
 &lt;pre class="bg-neutral-800 text-white p-4"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# 212.71.252.54 / 192.168.171.141 / node1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# 176.58.103.254 / 192.168.171.142 / node2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# 178.79.153.89 / 192.168.173.227 / node3&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Local hosts (on each server):&lt;/p&gt;

&lt;div class="group relative"&gt;
 &lt;button class="hidden group-hover:inline absolute top-0.5 right-0.5 bg-gray-200 p-2 hover:bg-gray-400"
 data-copy="true"&gt;copy&lt;/button&gt;
 &lt;pre class="bg-neutral-800 text-white p-4"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# local hosts
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;192.168.171.141 node1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;192.168.171.142 node2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;192.168.173.227 node3&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And remote (on my PC):&lt;/p&gt;</description></item></channel></rss>