Ilya Bylich

A lot of noisy output here, use grep to find what you need

Read this first

Ruby Marshalling from A to Z

Marshalling is a serialization process when you convert an object to a binary string.
Ruby has a standard class Marshal that does all the job for serialization and deserialization.
To serialize an object, use Marshal.dump, to deserialize - Marshal.load or Marshal.restore.

marshalled = Marshal.dump([1, 2, 'string', Object.new])
# => "\x04\b[\ti\x06i\aI\"\vstring\x06:\x06ETo:\vObject\x00"

Marshal.load(marshalled)
# => [1, 2, "string", #<Object:0x00000002643000>]

This article explains the format of marshalling and shows how to write a pure Ruby marshalling library
compatible with the standard Ruby implementation.

 The gem

Let’s try to make a pure Ruby gem that is compatible with standard Marshal class.

$ bundle gem pure_ruby_marshal
$ tree pure_ruby_marshal
pure_ruby_marshal
├── bin
│   ├── console
│   └── setup
├── CODE_OF_CONDUCT.md
├── Gemfile
├── lib
│   ├── pure_ruby_marshal
│  

Continue reading →


HandlerSocket + Ruby

 What is HandlerSocket (HS)

  • a plugin for MySQL
  • which allows you to read/write to MySQL
  • and gives you a separate connection to MySQL
  • and doesn’t allow you to run SQL queries
  • but allows to run simple CRUD queries only using indexes

HandlerSocket query language is very simple (I’d even say it’s primitive), but it’s much faster than MySQL’s one. Though, of course, there are some limitations. Interested?

 Installation

You already have it if you are using Percona Server or MariaDB. If not, install it from the source.

To activate the plugin, run:

INSTALL PLUGIN handlersocket SONAME 'handlersocket.so';

 Configuration

My configuration is the following:

# [mysqld] section
# the port number to bind to for read requests
loose_handlersocket_port = 9998
# the port number to bind to for write requests
loose_handlersocket_port_wr = 9999
# the number of worker threads for read requests

Continue reading →


Saving execution context for later debugging

Consider the following situation: you’ve 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.

 Binding

In Ruby the best candidate for doing this is Binding class. If you have a binding, your can easily do some debug using well-known pry gem. But the binding itself cannot be dumped (at least not, using default Ruby tools).

How to get a local binding? Just use binding. How to get a binding from an object? Just add a method to you class:

class MyClass
  def local_binding
    binding
  end
end

MyClass.new.local_binding
# => #<Binding>

Binding encapsulates the execution context

Continue reading →


Wrapping JavaScript library with Opal

 Introduction

The task that is solved here is not real, but it’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’s no fun. Instead, let’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’ve chosen a JS-based browser game called BrowserQuest written by Mozilla, and I’ll show you how to write a bot for it using Opal.

 Opal

There are so many posts about Opal, so I’m just going to say “it’s a Ruby to JavaScript” compiler, that’s enough.

 Environment

First of all, we need something that runs the game and injects a bot into the page. I, personally, while writing integration tests (this is the place, where we usually face to web

Continue reading →


Capybara and asynchronous stuff

In this entry I will try to cover the following aspects:

  1. Running asynchronous code in a web driver
  2. Making the call synchronous
  3. Wrapping it into some common solution
  4. Advanced example - working with IndexedDB from Capybara

 What is Capybara, Poltergeist and PhantomJS?

 PhantomJS

First of all, we need to know what is PhantomJS. I would say it’s a ‘tool that acts like a browser but can be controlled from outside using simple command interface’. In more common words, it’s a web driver. It’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.

 Poltergeist

Poltergeist is a Ruby wrapper for PhantomJS. Usually you write the code for PhantomJS on JavaScript, with Poltergeist you can run it on Ruby.

 Capybara

Well, I’m pretty sure you know what it is. It’s a test framework. And

Continue reading →


Apipie - amazing tool for documenting your Rails API

This article is about for Apipie gem (https://github.com/Apipie/apipie-rails) which provides a DSL for documenting your API. I will try to cover features that I personally use on my project.

Comparing to other tools for generating API documentation (yardoc, sdoc) 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.

Here is a simple example of how it looks in code:

class UsersController < ApplicationController

  resource_description do
    formats [:json]
    api_versions 'public'
  end

  api :POST, '/users' 'Create user'
  description 'Create user with specifed user params'
  param :user, Hash, desc: 'User information' do
    param :full_name, String, desc: 'Full name of the user'
    param :age, Fixnum, desc: 'Age of the user'
  end
  def create
    # Some application code
  end
end

Continue reading →


What is Ruby DSL

As you already know, DSL means domain-specific language. It’s like a language in a language. Here are some examples that we use every day:

class User
  attr_reader :name
end

class Profile < ActiveRecord::Base
  has_many :posts
end

class ApiController < ActionController::Base
  before_action :authenticate
end

But all these examples use rails-provided DSL, how about your own? First of all, you should know that all these methods (attr_reader, has_many and before_action) are actually class-methods of Module, ActiveRecord::Base and ActionController::Base. So you can write something like:

class TestClass
  def self.my_dsl_method(dsl_method_arg)
    puts "dsl method called with #{dsl_method_arg}"
  end
  my_dsl_method :some_argument
end

And the body of my_dsl_method can be more dynamic then just printing a string. It can define methods, execute some calculations, etc. Less words, more

Continue reading →


Experimental MySQL HTTP API and Ruby

Yes, MySQL has an HTTP API which is:

  1. an experimental feature
  2. it ships as a native plugin only for 5.7 version (http://labs.mysql.com/?id=3)

Basically, it allows you to work with your database in the following ways:

  1. as an SQL endpoint
  2. as a CRUD endpoint
  3. as a JSON document endpoint

 SQL endpoint

It gives an ability to run queries like

GET http://host:port/sql/:database/:query

For example

GET http://localhost:8080/sql/testdb/SELECT+1

is a synonym of SQL’s SELECT 1.

 CRUD endpoint

Interface is:

GET http://host:port/crud/:database/:table/:id

And

GET http://localhost:8080/crud/test_db/test_table/101'

produces:

SELECT * FROM `test_db`.`test_table` WHERE `test_table`.`id` = 101

 JSON document endpoint

Basically, with this endpoint your table has only 3 fields:

mysql> describe test_db.test_table;
+--------+---------------------+------+-----+---------+-------+
| Field  |

Continue reading →


ExceptionManager gem

ExceptionManager is a gem for getting extra information from your exception.

Source code: https://github.com/iliabylich/exception_manager

With this gem every time when you get an exception, it’s possible to grab subject of exception (the instance of class where raise happened), locals - local variables, subject_instance_variables and subject_class_variables

Examples:

require 'exception_manager'
ExceptionManager.enable!

class TestClassThatRaisesException
  @@class_variable = :class_value

  def test_error(*args)
    @instance_variable = :instance_value

    raise 'Test error'
  end
end

begin
  TestClassThatRaisesException.new.test_error(1, 2, 3)
rescue => e
  puts "Subject: #{e.subject}"
  puts "Locals: #{e.locals}"
  puts "Instance variables: #{e.subject_instance_variables}"
  puts "Class variables: #{e.subject_class_variables}"
  puts "Summary: #{e.summary.inspect}"
end

This

Continue reading →


Redis cluster. Quick overview

Today I’ve tested version 3.0.0 of Redis server with includes Redis cluster. Here are some first thoughts about this.

 Setup

Here are my servers:

# 212.71.252.54  / 192.168.171.141 / node1
# 176.58.103.254 / 192.168.171.142 / node2
# 178.79.153.89  / 192.168.173.227 / node3

Local hosts (on each server):

# local hosts
192.168.171.141 node1
192.168.171.142 node2
192.168.173.227 node3

And remote (on my PC):

# remote hosts
212.71.252.54  node1
176.58.103.254 node2
178.79.153.89  node3

First of all, let’s download and extract it (on each node).

mkdir build && cd build
wget http://download.redis.io/releases/redis-3.0.0.tar.gz
tar -xvzf redis-3.0.0.tar.gz
cd redis-3.0.0/

Now we can build it

apt-get install -y make gcc build-essential
make MALLOC=libc # also jemalloc can be used

Now let’s run tests

apt-get install -y tk8.5 tcl8.5
make test
# a lot of output, should be green

Continue reading →

ssl yes