Papers We Love: Feral Concurrency Control

This months PWL meeting discussed ‘Feral Concurrency Control: An Empirical Investigation of Modern Application Integrity’. The intended audience is database system researchers. It explains how popular application frameworks lean on ORM’s that disregard the database concurrency control solutions. Instead of using the databases system for foreign keys, constraints, and transactions they create a set of rules that perform in the application layer. The paper demonstrates how validations in the application layer give us inconsistent results.

Unique constraints are given as an example. When a field with a unique validation is created or modified in Rails, it will query the database to ensure that value does not already exist.

Applications with minimal traffic can be run with only one Ruby on Rails instance.

Initial Rails Application
User --> Ruby on Rails Application --> Database

As requests against the applicaion increase, we can add more Ruby on Rails instances to handle the traffic.

Ruby on Rails applications scaled to handle growing requests
         Ruby on Rails Application #1
User --> Ruby on Rails Application #2 --> Database
         Ruby on Rails Application #3 

In the experiment an application is bombarded with redundant data. In Figure 2 we see a blue line, the constant. This is the amount of duplicates without validation. The green line is the amount of duplication with validation. We can see with one running instance we have 0 duplicates. As soon as we start adding more instances the amount of duplicates jump.

As a Ruby developer with a history of Rails I was surprised at the accusations coming from the paper and discussion. Rails doesn’t prohibit us from using database concurrency control solutions. In my experience we have always used them.

This was really eye opening. I’m glad I went to this discussion and I’m thankful for the Seattle Chapter of Papers We Love. Many people come to Rails from boot camps or are self-taught. While ORM’s don’t prevent you from using the database it definitely encourages it to be blindly used as a storage system. It’s changed my thinking in how to help grow jr developers and the importance that needs to be placed on what’s happening in db/schema.rb.

Here is a list of resources I will be referencing in future conversations:
* Transactions
* Constraints vs Validations
* Postgres Explain

As a side note, validations where only inconsistent when compared to other records (am I unique, does this key exist). Validations performed consistently when evaluating data in the current record (is this a string and does it have a pattern?).

Nand2Tetris and HDL

In my local ruby group we’ve been working through Nand2Tetris. A program that walks through building a computer from logic gates to programing Tetris.

I’m struggling with the Hardware Description Language(HDL). I have built up assumptions about languages and their use of variables and functions. Below are my notes that have helped me straighten out how to work with HDL’s.


HDL is a markup language, like HTML or XML. We use this markup language to design logic gates. Logic gates will be described in syntax familiar to you as pseudocode. For example:

Chip Name: Or
 Inputs: a, b
 Outputs: out
 Function: If a=b=0 then out=0 else out=1.

HDL doesn’t have if/else syntax. This is telling us to use boolean arithmetic to create out=1 if a or b is 1.

Chip Body

The chip body is self explanatory. Here is the Or gate HDL file.

CHIP Or {
 //Declaring a Chip named 'or'. The definition is between the brackets.

IN a, b;
  OUT out;
  //Header of the chip. It declares the expected wires IN and OUT.

PARTS:
 //Here are the logical statements that describe how IN gets to OUT.
 Not(in=a, out=nota); // Invert a into nota
 Not(in=b, out=notb); // Invert b into notb
 Nand(a=nota, b=notb, out=out); // Nand's truth table will now output Or's truth table
 }

Statements

Statements will be a single line representing a chip and how it is used.

Not(in=a, out=nota);

If you looked at Not.hdl you would see in the Chip declaration an IN of in and and OUT of out. These names represent physical wires that are coming in and out of the chip.

in=a

Everything on the left side of ‘=’ is the name of the pin going in. Everything on the right is the name of the pin going out.

When you name a pin you can use characters (uppers & lowers), numbers, and ‘-‘. Pin names have to start with an lowercase letter.

In addition to pins, we can provide boolean values using ‘true’ or ‘false’.

Nand(a=in, b=true, out=out);

If we are only concerned with the input of ‘a’ we can supplement the input of ‘b’ with a boolean.

Not declaring a pin is not a problem. The HardwareSimulator will supplement it with false (0).

Nand(out=alwaystrue);
 //The a and b pins are not declared so their values
 // default to 0. Nand returns 1 if a and b are both 0.

We can also declare additional pins. Say we have a statement that declares the out pin but we also need that value for another statement.

Xor(a=a, b=b, out=sum);
 Or(a=a, b=sum, out=carry);

In this chip, ‘sum’ and ‘carry’ are the out pins. If we run this in the Hardware Simulator it will result in an error: “Can’t connect gate’s output to part:”.

Remember, ‘sum’ is a declared physical wire coming out of the chip. We cannot re-route it. However, we can declare additional outs:

Xor(a=a, b=b, out=ab, out=sum);
 Or(a=a, b=ab, out=carry);

Easily store hard coded values with Active Hash

Hard coded data is usually stored in the class that uses it.

#app/models/camper.rb
class Camper
  MEALS = {1: 'breakfast', 2:'lunch', 3: 'supper'}
 
end
 
Camper::MEALS

Active Hash is a library that helps Rails projects abstract this data out into an ActiveRecord like model:

#app/models/meals.rb
class Meals < ActiveHash::Base
  belongs_to :camper
 
  self.data = [
    { id: 1, name: 'breakfast'},
    { id: 2, name: 'lunch'},
    { id: 3, name: 'supper'}
  ]
end
 
#app/models/camper.rb
class Camper
  # required for ActiveRecord 3.1 or later
  extend ActiveHash::Associations::ActiveRecordExtensions
  has_many :meals
 
end
 
Camper.meals

This benefits our classes by removing data it’s not meant to represent. It helps the code architecture by not littering the application with constants. If someday we want that data to be an ActiveRecord model the code is already organized for it.

ActiveHash also works with FactoryGirl

FactoryGirl.define do
  factory :camper do
    name { 'Sally' }
    meals
  end
end