Meeting notes, October 2011

Skip to first unread message

Jesse Hallett

Oct 5, 2011, 4:42:30 AM10/5/11
PDXRuby 2011/10

Jesse Cooke worked on a Redis clone in Maglev for _why day. The code
is online at

There are non-persistent implementations of Redis in pure Ruby.

Lorentz operations are atomic thanks to Maglev transactions. Updates
block and retry until they succeed.

Lorentz calls "Maglev.abort_transaction" during a read or update.
This might be dangerous because it will clear any changes to
persistent objects that have not been committed. However, a future
release of Maglev will support nested transactions, which will
alleviate this problem.

At RubyConf, there was a lot of talk about concurrency in Ruby. Jesse
proposes a documentation project to make it easier to learn about the
different concurrency options that are available. The docs will be
hosted at and at He wants
to know what you want out of such a project?

Vagrant, your first virtual environment - a presentation by Igal Koshevoy.

If you are working with a bunch of other developers, everyone has
their own OS version, Ruby version, gem version, etc. That makes
development hard - especially when every dev has to compile Redis.

Vagrant is a virtualized development environment. You can create one
VM configuration and distribute it to every developer. Vagrant mounts
your project development directory in the VM; so your app runs in this
standardized environment while you are working on it; but you still
get the advantages of working on your local machine.

In addition to mounting your development files in the VM, Vagrant also
sets up port-forwarding for you so that you can access your running
application in your local web browser.

Igal likes to use NFS sharing to synchronize files between his
development directory and the VM because NFS is faster than Vagrant's
default folder sharing option.

Hooks for provisioning your VM are built in; and you can swap out
provisioning tools. Igal uses Chef Solo; but you can also use regular
Chef or Puppet. Once a VM is set up a provisioning recipe is run to
install all of the software required for development.

Vagrant is great for code sprints. For example, when people get
together to work on Calagator they tend to spend a lot of time getting
set up for development. By using Vagrant we can skip that process.

The typical procedure when running Vagrant is to download a stock VM
image, maintained by the Vagrant team that is then customized by your
Chef or Puppet recipe. But you can also create and host your own VM

Vagrant uses VirtualBox to run VMs. VirtualBox has a great API for
this kind of stuff. Unfortunately, under Oracle's stewardship
VirtualBox has lagged behind the state-of-the-art - so some other VM
hosts are now a bit faster.

To run your app in the VM, the standard procedure is to use SSH to log
into the VM and to execute your startup scripts and tests there. But
what if you or your coworkers use an IDE and cannot easily run code
via SSH? Remote debugging support in IDEs may provide the answer. Or
you might try using scripts that encapsulate an SSH session and proxy
STDOUT for you. Suggestions on this issue are welcome.

Markus Roberts explains that emulation is more robust now than it used
to be thanks to emulators that simulate the entire hardware layer and
thanks to CPUs that provide hardware-level emulation support.

Metaprogramming and ePDX: Portland's Tech Directory, presented by Igal

ePDX, Portland's Tech Directory, is a web site where individuals and
organizations can post profiles with pictures. The site runs on
Citizenry <>, which uses Paperclip
to handle the picture uploads. The typical way to use Paperclip would
have involved duplicating code in four different models. Instead,
Igal used metaprogramming to write the code once and to provide to
each model class as a module.

Igal used Yard to document the many options available in the methods
that he wrote. Yard pulls out inline comments to build documentation.
It provides markup for describing method arguments, expected types,
and hash-based options.

Igal really did use a lot of fancy metaprogramming. He managed to
reduce the code required in each model class to a single line.

Remember folks, "include" adds instance methods to a class; "extend"
adds methods directly to its receiver, which can be any object. If
you call "extend" in a class definition without an explicit receiver
it will add module methods as class methods.

Konstantin Haase, the maintainer of Sinatra, jumps up to give us a
little tour of metaprogramming in Sinatra. Sinatra uses
"define_method" to internally define method names with characters that
are not allowed when declaring methods with "def". The idea is that
this produces nicer stack traces. For example:

most recent call last:
get /name : line 2

Where the method name that was actually invoked is "get /name". They
also unbind these methods, immediately after defining them, but before
invoking them, so that they do not appear in lists of method names on
a given class.

The Sinatra "compile!" is an internal method that transforms routes
described in the Sinatra DSL into executable methods. "compile!"
compiles your routes slightly differently depending on whether your
route block lists one or zero arguments. Normally if a block is
defined to accept zero arguments and you give it one Ruby will
complain. Sinatra checks the "arity" of the given block and patches
this problem for you.

Sinatra 1.3 was released a few days ago. It includes a new streaming
API! You can stream out HTTP responses with the "<<" operator. You
can also use code like this to keep a connection open and get its
reference back later:

stream(:keep_open) { |out| connections << out }

Connections that are kept open can block until the response is
finished - or you can keep the stream open without blocking if you are
using a non-blocking server. You can also return a proper Deferred
instance from an action for compatibility with EventMachine.

BTW, Konstantin uses TextMate.

The Sinatra team will continue to release Sinatra 1.2 bug fixes.
Those bugfix releases will always be comlatible with MRI 1.8.6.

Padrino <> provides some extra libraries to
extend the functionality of Sinatra. It lets you turn Sinatra into
Rails, one feature a time. If there are features that you don't want,
just don't include them.

# Job Postings

Monty, representing BikeTrack, is looking for a software programmer.
They are making small GPS devices for tracking down stolen bikes.
They need a web app for bike profiles, a server that collects data
from UDP streams, and a server to send push notifications to smart
phones. They are looking for Ruby or Python programmers in

Paydici is hiring too. The are looking for a programmer to become the
third member of the Paydici development team, and for someone to fill
a development lead role. Paydici is an online payment solution. They
say that they offer fun, sane Rails work. Talk to Reid Beels or Bryan

Jive is looking for a passionate JavaScript programmer. Most of the
development at Jive is in Java. But there is a dedicated JavaScript
team there too. If you are so inclined, you can work on JavaScript
full-time at Jive and probably learn a lot in the process. Talk to
Jesse Hallett.

Kevin Chambers with Ride Connection is looking for a programmer. Ride
Connection develops scheduling and dispatch software for nonprofits,
such as senior centers.

Keith Swallow, from Goldstar, is looking for a dev-ops person. They
will also be at the DevOps meetup on the 17th. The Goldstar team is
distributed, but they are hoping to find a dev-ops person in Portland.

Jesse Cooke notes that there are not enough programmers in Portland to
meet demand, and urges everyone to convince their friends to move

Igal Koshevoy

Oct 5, 2011, 6:50:30 PM10/5/11
Thank you Jesse for doing a fantastic job documenting the meeting again. Awesome!

Say, I've resolved the issues I ran into yesterday with the Vagrant environment for Calagator. You may be interested in the following files, which you're welcome to use in your own projects:

I realize my demo didn't show Vagrant in its best light, but the surprises gave us more reason to talk issues you'll face using it. Dealing with Vagrant, provisioning and such can be tricky, but there's still a huge benefit to being able to maintain a single Vagrant configuration that all your developers can use and that you can debug on your on machine, rather than having to go to each dev's computer to figure out what's wrong with their hand-built environment.

For the curious, here are issues I had to deal with recently:
* Vagrant made a backwards incompatible change to their "lucid32" box, which is the base installation of Ubuntu I rely on for my VM.
* The new box features a custom-compiled Ruby, rather than using the Ubuntu Ruby packages.
* The new custom-compiled Ruby fails in bizarre ways if some Ubuntu Ruby packages are installed, such as the ones I had my provisioning install because they were needed in the past.
* The new custom-compiled Ruby isn't visible in the PATH to non-login shells, such as the provisioning, which requires a workaround.
* The new custom-compiled Ruby is added to a shell's PATH in a different order than in the past, so my code for telling the system how to find the "bin" scripts installed by gems was failing because it couldn't find Ruby yet.
* Bundler's pervasive insanity is further exacerbated by Chef's screwy behavior when using "execute" as a user, making Bundler sometimes use the wrong directory and fail with cryptic errors. In specific, running the provisioning through the "vagrant" wrapper caused Bundler to use a different directory than running the provisioning directly from a shell -- gah!
* I added a mechanism to locally cache the ".deb" packages downloaded by "apt-get" so I could do a "vagrant destroy; vagrant up" to quickly rebuild the VM, without downloading all the packages again. Being able to rebuild the VM from scratch quickly makes it much easier to verify that it really works.

Morals of the story? Accept that you'll face unpleasant surprises as new versions of software are released if you don't maintain copies of all files used by your environment -- e.g. if your fetching a Vagrant box, gem or package off the Internet, it may randomly disappear or be replaced by something crazy, or just as crazy, but in a way that your old workarounds can't cope with. Seriously consider at least maintaining your own Vagrant box as the base image to avoid catastrophic WTFs if they totally redo things. Rebuild the box from scratch to ensure your provisioning works as expected, simply reapplying the provisioning to an existing box is not enough.

Also, sorry for eating up time at the meeting going through these WTFs. I hadn't intended on that detour and thought we'd have more time to talk about RubyConf. Oh well, we'll hopefully talk about that next month.


Jason LaPier

Oct 5, 2011, 8:30:22 PM10/5/11
Because of my schedule I don't get to many PDX.rb meetings any more, and I just want to give a big thank you to Jesse - your meeting notes are always superb! Thanks for tracking so much info, Jesse. I can almost... almost imagine being there...

- Jason L.

You received this message because you are subscribed to the Google Groups "pdxruby" group.
To post to this group, send email to
To unsubscribe from this group, send email to
For more options, visit this group at

Reply all
Reply to author
0 new messages