2011
How to listen to Stravinsky's Rite of Spring
Igor Stravinsky’s The Rite of Spring is an amazing piece of classical music. It’s one of the rare pieces that was really revolutionary in its time. But in our time, almost one hundred years on, it doesn’t sound that different.
Music has moved on. We are used to the odd times of “Take Five” and the dissonant horns of a John Williams soundtrack. Music offending the status quo is nothing unheard of.
To enjoy Rite of Spring in its proper context, you have to forget all that. Put yourself in the shoes of a Parisian in 1913, probably well off. You probably just enjoyed a Monet and a coffee. But your world is changing. Something about workers revolting. A transition from manual labor to mechanical labor.
Now imagine yourself at the premier for this new ballet from Russia. You being a Parisian, you’re probably expecting something along the lines of Debussy or perhaps Debussy or Berlioz.
Instead, you get mild dissonance and then total chaos. The changing time signatures, the dissonance, the subject of virgin sacrifice. You’d probably riot too!
Practical words on mocking
Practical Mock Advice is practical:
Coordinator objects like controllers are driven into existence because you need to hook two areas of your application together. In Rails applications, you usually drive the controller into existence using a Cucumber scenario or some other integration test. Most of the time controllers are straightforward and not very interesting: essentially a bunch of boilerplate code to wire your app together. In these cases the benefit of having isolated controller tests is very little, but the cost of creating and maintaining them can be high.Includes the standard description of how to use mocks with external services. But more interesting are his ideas and conclusions on when to mock, how to mock caching implementations, and how to mock controllers/presenters/coordinator objects.A general rule of thumb is this: If there are interesting characteristics or behaviors associated with a coordinator object and it is not well covered by another test, by all means add an isolated test around it and know that mocks can be very effective.
Locking and how did I get here?
I've got a bunch of browsers tabs open. This is unusual; I try to have zero open. Except right now. I'm digging into something. I'm spreading ephemeral papers around on my epemeral desk and trying to make a concept, not ephemeral, at least in my head.
It all started with locking. It's a hard concept, but some programs need it. In particular, applications running across multiple machines connected by imperfect software and unreliable networks need it. And this sort of thing ends up being difficult to get right.
I've poked around with this before. Reading the code of some libraries that are implementing locking in a way that might come in handy to me, I check out some documentation that I've seen referenced a couple times. Redis' setnx
command can function as a useful primitive for implementing locks. It turns out (getset
) is pretty interesting too. Ohm, redis-objects and adapter-redis all implement locking using a combination of those two primitives. Then I start to dig deeper into Ohm; there's some interesting stuff here. Activity feeds with Ohm is relevant to my interests. I've got a thing for persistence tools that enumerate their philosophy. Nest seems like a useful set of concepts too.
I'm mentally wandering here. Let's rewind back to what I'm really after: a way to do locking in Cassandra. There's a blog post I came across before on doing critical sections in Cassandra, but it uses ZooKeeper, so that's cheating. Then I get distraced by a thing on HBase vs. Cassandra and another perspective on Cassandra that mentions but does not really focus on locking.
And then, paydirt. A wiki page on locking in Cassandra. It may be a little rough, and might not even work, but it's worth playing with. Turns out it's an adaptation of an algorithm devised by Leslie Lamport for implementing locking with atomic primitives. It uses a bakery as an analgoy. Neat.
Then I get really distracted again. I remember doozer, a distributed consensus gizmo developed by Blake Mizerany at Heroku. I get to reading its documentation and come across the protocol spec, which has an intriguing link to a Plan 9 manpage on the Plan 9 File Protocol. That somehow drives me to ponder serialization and read about TNetstrings.
At this point, my cup has overfloweth. I've got locking, distributed consensus, serialization, protocols, and philosophies all on my mind. Lots of fun intellectual fodder, but I'll get nowhere if I don't stick my nose into one of them exclusively and really try to figure out what it's about. So I do. Fin.
Refactor to modules, for great good
Got a class or model that’s getting a little too fat? Refactor to Modules. I’ve done this a few times lately, and I’ve always liked the results. Easier to test, easier to understand, smaller files. As long as you’ve got a tool like ctags
to help you navigate between methods, there’s no indirection penalty either.
That said, I’ve seen code that is overmodule’d. But, that almost always goes along with odd callback structures that obscure the flow-of-control. As long as you stick to Ruby’s method lookup semantics, it’s smooth sailing.
ZeroMQ inproc implies one context
I’ve been tinkering with ZeroMQ a bit lately. Abstracting sockets like this is a great idea. However, the Ruby library, like sockets in general, is a bit light on guidance and the error messages aren’t of the form “Hey dumbie, you do it in this order!”
Here’s something that tripped me up today. ZeroMQ puts everything into a context. If you’re doing in-process communication (e.g. between two threads in Ruby 1.9), you need to share that context.
Doing it right:
# Create a context for all in-process communication
>> ctx = ZMQ::Context.new
# Set up a request socket (think of this as the client)
>> req = ctx.socket(ZMQ::REQ)
# Set up a reply socket (think of this as the server)
>> rep = ctx.socket(ZMQ::REP)
# Like a server, the reply socket binds
>> rep.bind('inproc://127.0.0.1')
# Like a client, the request socket connects
>> req.connect('inproc://127.0.0.1')
# ZeroMQ only knows about strings
>> req.send('1')
=> true
# Reply/server side got the message
>> p rep.recv
"1"
=> "1"
# Reply/server side sends response
>> rep.send("urf!")
=> true
# Request/client side got the response
>> req.recv
=> "urf!"
Doing it wrong:
# Create a second context
>> ctx2 = ZMQ::Context.new(2)
# Create another client
>> req2 = ctx2.socket(ZMQ::REQ)
# Attempt to connect to a reply socket, but it doesn't
# exist in this context
>> req2.connect('inproc://127.0.0.1')
RuntimeError: Connection refused
from (irb):16:in `connect'
from (irb):16
from /Users/adam/.rvm/rubies/ruby-1.9.2-p180/bin/irb:16:in `'
I believe what is happening here is that each ZMQ::Context
gets a thread pool to manage message traffic. In the case of in-process messages, the threads only know about each other within the confines of a context.
And now you know, roughly speaking.
Booting your project, no longer a giant pain
So your app has a few dependencies. A database here, a queue there, maybe a cache. Running all that stuff before you start coding is a pain. Shutting it all down can prove even more tedious.
Out of nowhere, I find two solutions to this problem. takeup seems more streamlined; clone a script, write a YAML config. foreman is a gem that defines a Procfile
format for defining your project’s dependencies. Both handle all the particulars of starting your app up, shutting it down, etc.
I haven’t tried either of these because, of course, they came out the same week I bite the bullet and write a shell script to automate it on my projects. But I’m very pleased that folks are scratching this itch and hope I’ll have no choice but to start using one when it reaches critical goodness.
Ruby's roots in AWK
AWK-ward Ruby. One man Unix wrecking squad Ryan Tomayko reflects on aspects of Ruby that arguably grew from AWK more than Perl. Great archaeology, but also a good gateway drug to understanding how awk is a useful tool. Only recently have I started to really grok awk, but it’s super handy for ad-hoc data munging in the shell.
Humankind's genius turned upon itself
When We Tested Nuclear Bombs. An absolutely fantastic collection of photos from the nuclear test program. Beautiful to look at, terrifying to contemplate the ramifications in context. It’s harrowing to think that one of science’s greatest achievements could undo so much of science’s achievement.
Burpess and other intense workouts
But when pressed, he suggested one of the foundations of old-fashioned calisthenics: the burpee, in which you drop to the ground, kick your feet out behind you, pull your feet back in and leap up as high as you can. “It builds muscles. It builds endurance.” He paused. “But it’s hard to imagine most people enjoying” an all-burpees program, “or sticking with it for long.”I'm having trouble deciding whether I should say good things about burpees. I only do a handful at a time, usually as part of a series of movements. They're not so bad if you start with just a few and work up from there.
Burpees aside, it’s interesting to see opinions on what the most useful exercise movements are. I’m really glad I don’t need to start doing butterflies though.
Don't complain, make things better
notes on “an empathetic plan”:
Worse is when the the people doing the complaining also make software or web sites or iPhone applications themselves. As visible leaders of the web, I think there are a lot of folks who could do a favor to younger, less experienced people by setting an example of critiquing to raise up rather than critiquing to tear down.Set agreement to maximum. If you’re complaining on Twitter just to make yourself feel better, keep in mind that some of us are keeping score.If you’re a well known web or app developer who complains a lot on Twitter about other people’s projects, I am very likely talking about you. You and I both know that there are many reasons why something works a certain way or why something in the backend would affect the way something works on the front-end.
Don’t waste your time griping and bringing other people down. Spend your time making better things.
Perfection isn't sustainable
When an interesting person is momentarily not-interesting, I wait patiently. When a perfect organization, the boring one that's constantly using its policies to dumb things down, is imperfect, I get annoyed. Because perfect has to be perfect all the time.More and more, I think perfection is the biggest enemy of those who want to ship awesome things. Iteration can lead to moments of perfection, but perfection is not sustainable over time.
Using Conway's Law for the power of good
Michael Feathers isn’t so quick to place negative connotations on Conway’s Law. Perhaps it’s not so much that organizations don’t communicate well, the traditional reading of Conway’s Law. Maybe as organizations grow, people tend to only communicate frequently with a few people and those interactions end up defining the API layers.
I’ve been thinking about this a bit lately. It’s possible there’s something to be said about using Conway’s Law to your advantage when building service-based shearing layers. Some parts of your application should evolve quickly, others require more stability. Some iterate based on user and conversion testing, others iterate as TDD or BDD projects. You can discover these layers by observing team interactions and using Conway’s Law to define where the APIs belong.
Hell is other people's concurrency
The first rule of evented programming is, don’t block the event loop! Mathias Meyer’s great intro to Ruby’s EventMachine library. Non-blocking IO is so hot right now. But remember, it’s just a tool on your concurrency utili-belt. Remember to reach for coroutines, threads, actors, and STMs too.
Bloom, a language with time travel
Bloom, a language for disordered (whut!) distributed programming with powerful consistency analysis and concise, familiar syntax (the prototype is built on Ruby):
Traditional languages like Java and C are based on the von Neumann model, where a program counter steps through individual instructions in order. Distributed systems don’t work like that. Much of the pain in traditional distributed programming comes from this mismatch: programmers are expected to bridge from an ordered programming model into a disordered reality that executes their code. Bloom was designed to match–and exploit–the disorderly reality of distributed systems. Bloom programmers write programs made up of unordered collections of statements, and are given constructs to impose order when needed.Interested to see how languages will push the assumption that time proceeds from earlier to later as one reads down a source file.
The rules of the yak shave
Yak shaves. They’re great fun. Like most things, yak shaving is more fun when you have some rules to guide you away from the un-fun parts:
- always have a goal, know when you’re done
- timebox it
- work on a branch so you can switch to real work if you need to
- make smaller commits than usual so you can unwind if you should go awry
- don’t worry about writing tests if you don’t know what you’re doing
- if you aren’t sure where you are going, write a test harness and iterate on that
- have a pair or buddy to talk through what you’re trying to do and how to get there
- bail out if you are starting to burn out, face diminishing returns, or think of a better way to shave they yak
Linux screenshot nostalgia
Anyone else remember uploading screenshots of their super awesome, tweaked out Linux hacker desktops?
Sorry, I'm not running WindowMaker, Enlightenment, or Sawmill anymore. Besides that, I think I have all the cliches: terminal, editor, MP3 player, system monitors, blinkenlights, etc. I am missing an IRC session, though.