Rails 4.2 new gems: active job and global id

A few days ago the new rails 4.2 beta release was announced and the usual bag of goodies is going to make our life as developers easier and more interesting.

The most relevant new feature is the Active Job framework and its integration with ActionMailer: rails has now its own queue interface and you can swap the queuing gem (resque, delayed job, sidekiq…) without changing your application code.
You can even send email asyncronously with the new deliver_later method, while if you want sync delivery you should use instead deliver_now because the old deliver method is now deprecated.
If you don’t add any queue gem to the Gemfile then the default rails system will be used, which means that everything will be sent immediately (no async functionality).

This brilliant feature depends on a couple of new gems: active job and global id. Active Job usage is well documented in the new official guide, so I will focus most of this article on Global Id.
If you want to follow along you can download a demo app from this repository, bundle the gems and start the server with rails s. The example is basically a rails 4.2 app with a regular ActiveRecord Friend scaffold and a NameCapitalizerJob job class.

How do the new gems interact exactly? Let’s enqueue a new job for the NameCapitalizerJob worker, which is located in the example application:

  NameCapitalizerJob.enqueue Friend.first
  => #<NameCapitalizerJob:0x007fb44acaff48 ...>

If you used rails queuing systems in the past you already know that it was necessary to pass your ActiveRecord objects to the worker in the form of their id and manually reload the record at job execution. This is no more required, so in the example above we’re simply passing the record itself, while in the job code the reload is automatic:

NameCapitalizerJob < ActiveJob::Base
  def perform(friend)
    name = friend.name.capitalize
    friend.update_attribute :name, name
  end
end

You can see the job has been correctly enqueued:

Delayed::Job.count
 => 1

with the following params:

YAML.load(Delayed::Job.first.handler).args
 => [NameCapitalizerJob, "4a33725b-35cf-4940-b1ca-d6fad84d410f", "gid://activejob-example/Friend/1"]

These params represent: the job class name, the job id, and the global id string representation for the Friend.first record.
The format of the global id string is gid://AppName/ModelClassName/record_id.
Given a gobal id, the worker will load the referenced record transparently. This is achieved by mixing into ActiveRecord::Base a module from the global id gem:

puts ActiveRecord::Base.ancestors
...
GlobalID::Identification
...

The GlobalID::Identification module defines only a couple of methods: #global_id, #signed_global_id and their aliases #gid and #sgid, where the first is the record’s globalid object, the second is the record’s signed(encrypted) version of the same object:

gid = Friend.first.gid
 => #<GlobalID:0x007fa9add041f8 ...>
gid.app
 => "activejob-example" 
gid.model_name
 => "Friend" 
gid.model_class
 => Friend(id: integer, name: string, email: string...)
gid.model_id
 => "1"   
gid.to_s
 => "gid://activejob-example/Friend/1"

sgid = Friend.first.sgid
 => #<SignedGlobalID:0x007fa9add15e58 ...>
sgid.to_s
 => "BAh7CEkiCGdpZAY6BkVUSSIlZ2lkOi8vYWN0aXZl..."

The most important thing here is the string representation of the gid, as it contains enough information to retrieve its original record:

GlobalID::Locator.locate "gid://activejob-example/Friend/1"
 => #<Friend id: 1, name: "John smith" ...>

The actual source code used for locating records is rather simple and self explanatory:

class ActiveRecordFinder
  def locate(gid)
    gid.model_class.find gid.model_id
  end
end  

Regarding the signed object, we can inspect the original data hidden into its string representation using the following code:

SignedGlobalID.verifier.verify sgid.to_s
 => {"gid"=>"gid://activejob-example/Friend/1", "purpose"=>"default", "expires_at"=>Mon, 29 Sep 2014 08:25:31 UTC +00:00}

That’s how the global id gem works inside rails. By the way, it’s rather easy to use it with your own classes. Let’s see how to do it.
Let’s start a new irb session with bundle exec irb from the app folder, and require it with require 'globalid'.
The needs an app namespace in order to generate ids, so we need to set it manually:

GlobalID.app = 'TestApp'

Now let’s build a PORO class that defines globalid required methods (::find and id) and includes the GlobalID::Identification module:

class Item
  include GlobalID::Identification
  
  @all = []
  def self.all; @all end
  
  def self.find(id)
    all.detect {|item| item.id.to_s == id.to_s }
  end
  
  def initialize
    self.class.all << self
  end
    
  def id
    object_id
  end
end

As you might guess, the ::find method retrieves an item from its id code, while the #id method is simply an identifier. It works like this:

  item = Item.new
   => #<Item:0x007fdb4b05da10>
  id = item.id
   => 70289916620040 
  Item.find(id)
   => #<Item:0x007fdb4b05da10>

Time to get the item global id:

  gid = item.gid
   => #<GlobalID:0x007fdb4b026358 ...>
  gid.app
   => "TestApp"
  gid.model_name
   => "Item"
  gid.model_id
   => "70289916620040"
  gid_uri = gid.to_s
   => "gid://TestApp/Item/70289916620040"

We can now retrieve the original Item object from the gid_uri:

found = GlobalID.locate gid_uri
 => #<Item:0x007fdb4b05da10>
found == item
 => true

That’s it! I encourage you to check out the global id gem code on github, it’s just a few files so it’s very readable.

3 Simple examples from Ruby to Elixir

In this post we’re gonna see how to transform a simple script from Ruby to Elixir.

Installing Elixir

The first thing you need is to have Elixir installed on your box, the instructions are dead simple and you can
find them in the official Getting Started page.
For example on OS X is as simple as brew update; brew install elixir.

The Ruby Script

The script is the one I use to fire up my editor adding support for the file:line:column
format that is often found in error stacktraces. I keep this script in ~/bin/e.

#!/usr/bin/env ruby

command = ['mate']

if ARGV.first
  file, line_and_column = ARGV.first.split(':', 2)

  command << file
  command += ['-l', line_and_column] if line_and_column
end
command << '.' if command.size == 1
exec *command

Take 1: Imperative Elixir

As we all know, no matter the language, you can keep your old style. In this first example we’ll see the same

#!/usr/bin/env elixir

if System.argv != [] do
  [file| line_and_column] = String.split(hd(System.argv), ":", parts: 2)
  args = [file]

  if line_and_column != [] do
    args = args ++ ["-l"| line_and_column]
  end
else
  args = ["."]
end
System.cmd("mate", args)

The “Guillotine” operator

The first thing we notice the change in syntax for the splat assignment:

# Ruby
a, b = [1,2,3]
a # => 1
b # => 2
# Elixir
[a| b] = [1,2,3]
a # => 1
b # => [2,3]

The | operator in Elixir will in fact take out the head of the list and leave the rest on its right.
It can be used multiple times:

[a| [b| c]] = [1,2,3]
a # => 1
b # => 2
c # => [3]

what happens here is that the list that in the first example was b is now beheaded again.
If instead we wanted c to equal 3 the assignment would look like this:

[a| [b| [c]]] = [1,2,3]
a # => 1
b # => 2
c # => 3

As we can see Elixir matches the form of the two sides of the assignments and extracts values and variables accordingly.

Other notes

Let’s see a couple of other things that we can learn in this simple example

List concatenation: ++

The ++ operator simply concatenates two lists:

a = [1,2] ++ [3,4]
a # => [1,2,3,4]

Double quoted "strings"

All strings need to be double quoted in Elixir, as single quotes are reserved for other uses.
I make the mistake of using single quotes all the time. Probably that’s the price for being a
ROFLScale expert.

Take 2: First steps in Pattern Matching

With this second version we’re gonna see the pattern matched case.

Notice anything?

Yes. All ifs are gone.

#!/usr/bin/env elixir

args = System.argv
args = case args do
  [] -> []
  [""] -> []
  [path] -> String.split(path, ":", parts: 2)
end

args = case args do
  [] -> ["."]
  [file] -> [file]
  [file, ""] -> [file]
  [file, line_and_column] -> [file, "-l", line_and_column]
end

System.cmd("mate", args)

We now reduced the whole program to a couple of switches that will route the input and transform it
towards the intended result.

That’s it. No highlights for this implementation. Just a LOLCAT.

cat getting scared for no reason

Take 3: Modules and pipes

#!/usr/bin/env elixir

defmodule Mate do
  def open(argv), do: System.cmd("mate", argv |> parse_argv)

  def parse_argv([]), do: ["."]
  def parse_argv([options]) do
    [file| line_and_column] = String.split(options, ":", parts: 2)
    [file| line_and_column |> line_option]
  end

  def line_option([]),                do: []
  def line_option([""]),              do: []
  def line_option([line_and_column]), do: ["-l", line_and_column]
end

Mate.open System.argv

Module and defs

As you have seen we have now organized out code into a module and moved stuff to defined module
functions. The same function can be defined multiple times, Elixir will take care of matching the arguments
you pass to a function to the right.

Let’s review the two forms of function definition:

defmodule Greetings do
  # extended
  def hello(name) do
    IO.inspect("hello #{name}")
  end

  # onliner
  def hello(), do: IO.inspect("hello world!")
end

Greetings.hello "ppl" # => "hello ppl"
Greetings.hello       # => "hello world!"

Be sure to remember the comma before do: otherwise Elixir will complaint.

The |> pipe operator

If you’re familiar with commandline piping you’ll fell like at home with the pipe operator.
Basically it will take the result of each expression and pass it as the first argument of the next one.

Let’s see an example:

"hello world" |> String.capitalize |> IO.inspect # => "Hello world"

That is just the same of:

s = "hello world"
s = String.capitalize(s)
s = IO.inspect(s)
s # => "Hello world"

or

IO.inspect(String.capitalize("hello world")) # => "Hello world"

Where the latter is probably the least comprehensible to human eyes

What’s next?

Playing

Studying

Watching

Barebon, a minimal prototyping framework based on Bourbon and Neat

Say hello to the first, unpolished version of Barebon!

Barebon is a simple skeleton boilerplate for fast static page prototyping. It provides a friendly environment for front-end developers who love Sass and CoffeeScript. It also comes with a super-easy Grunt configuration that helps you to start hacking on your project right away.

Why?

Legit question! I absolutely love and use HTML5 boilerplate and Yeoman, but when it comes to super-simple static pages prototyping they’re just… overkill. I just wanted a neat, easy “framework” for these kinds of websites.

Since I’ve been enjoying Bourbon and Neat for a while I’ve decided to give it a try and make something focused on that. I liked it, so I thought I could share it with teh internetz.

How easy is it?

VERY easy. If you already have npm and grunt-cli installed, you just need to fork the repo, get in the folder and run $ npm install. When done, you just need to spawn the grunt watcher (that includes a Livereload feature), and you can start hacking on your code! 

Gimme dat repository link already!

Ok, ok! You can find Barebon on Github. Feel free to give it a try – any feedback is obviously appreciated!

Wordpress and OpsWorks, “Pride and Prejudice” (Part 2)

Here we are for Part 2 :)

In my last post about WP and OpsWorks I tried to explain the general setup for the recipes that I’ve developed to automate the deploy of WP applications through OpsWorks. If you missed it here's the link.

Today I’m gonna talk about a particular problem that I encountered while writing the recipe that currently handles the database importation.

As anyone with a little bit of experience in WP knows, applications developed on top of it are tightly coupled with the database and so their deploy differs from the one related to applications developed on top of frameworks like Rails or Laravel.

To handle the over mentioned importation I decided to keep it simple and stupid (and dirty!) and put the dump right in the repo. In this way it is automatically available during the deploy after the git fetch performed on the instance by the Amazon infrastructure.

Given the possibility to have or not the dump wherewith seed the database, I encountered the need to check for its presence. 

And here’s the first problem:

 
db_path = File.join(deploy[:deploy_to], 'current/dump.sql')

if File.file? db_path 

  # Do stuff like import the database 
  
  ... 
  
end

If you check for the presence of the dump in this way you’ll end up with a broken deploy when you remove the dump after a proper importation.

This is due the fact that the recipes that get executed by the Amazon infrastructure are actually compiled and so the check will be true even after the first time you remove the dump from the repo.

After a bit of Google, StackOverflow and Chef docs I found that the check should have been wrapped inside a ruby_block Chef resource.

Everything that is done inside this kind of resource is in fact evaluated dynamically right during the execution of the recipe where it is used. Not only what is written inside the block do end but also the proc passed to the not_if guard.

Here’s the proper check:


db_path = File.join(deploy[:deploy_to], 'current/dump.sql')

ruby_block 'magic_dynamic_evaluation' do
  not_if { File.file? db_path }
  block do
  
    # Do stuff like import the database
    ...

  end
  notifies :run, 'resource[resource_name]', :immediately
end

With regard to the last element inside the ruby_block (i.e. notifies :run, 'resource[resource_name]', :immediately) it really deserves a proper dissertation because it takes into consideration the notification system implemented by Chef. Here you can find a brief doc about it.

Anyway what the last statement inside the ruby_block do is “simply” notify another resource immediately (i.e. :immediately) after and if (i.e. not_if) it is run (i.e. :run).

Next time I’ll try to explain another functionality that I’ve put inside the recipe that I’ve briefly introduced in this post so stay in touch! ;)

つづく

Web Procedural Map Generation - Part 3

As I stated in my last post about map generation, I was satisfied by Voronoi as a map representation system, but it was not the right tool for me because I needed a wrap-wround map.

After some googling I found another great post by Amit Patel that describes  in great detail hexagonal maps, so I decided to use an hexagonal grid for my map. It seemed a good compromise.

Good and fascinating. A regular hexagon:

  • can be inscribed inside a circle;
  • is composed of six equilateral triangles with 60° angles inside;
  • is composed by six edges and six vertices, each edge having the same size.

There are a lot of other interesting facts about hexagons. Last but not least hexagons can be easily found in nature (e.g. honeycombs) and it’s often considered nature’s perfect shape:

image

Back to my goal of map generation, hexagonal maps are not so easy to deal with due to the nature of the hexagons themselves. As Amit’s says:

Squares share an edge with four neighbors but also touch another four neighbors at just one point. This often complicates movement along grids because diagonal movements are hard to weight properly with integer movement values. You either have four directions or eight directions with squares, but with hexagons, you have a compromise—six directions. Hexagons don’t touch any neighbor at only a point; they have a small perimeter-to-area ratio; and they just look neat. Unfortunately, in our square pixel world of computers, hexagons are harder to use…

In any case, having found no libraries to deal with hexagons in js, I decided to write one: hexagonal.js. I tried to give the library enough flexibility to be used following any of the approaches described by Amit in his post. At the moment some features are still missing (like the cube coordinates) but I’ll add them in the next few days along with demos and better documentation.

Here you can find a codepen demo that uses an hexagonal map and a heightmap.