My first Rails commit

A small patch I wrote is included in Rails 3.2.3, which I’m rather proud of — while my commit isn’t very many lines of code, it was a serious feat to figure it out.

It solves (or minimizes) a race condition waiting for a free connection from the ConnectionPool in multi-threaded ActiveRecord use. 

Sadly, the functionality I improve has been removed from Rails master (to be Rails4), and tenderlove is dead set against adding it back in. So my contribution has a limited lifespan of usefulness.  On the other hand, I think I’m probably not the only one who actually needs the functionality tenderlove is removing (if you do multi-threaded use of ActiveRecord, you want to pay attention that issue/discussion linked above) — so maybe my hard-earned improvement will end up ressurected in an add-on or monkey-patch to ActiveRecord restoring ConnectionPool’s ability to let M threads share N connections.

There’s also another (actually more serious) issue related to multi-threaded Rails use in 3.2.0-3.2.2 that I found, but tenderlove rewrote my pull request instead of accepting it as is, so I don’t get a git log credit for that one.

While my patch(es) weren’t very much code, getting to those few lines of code was a serious battle. Understanding and debugging multi-threaded race conditions is hard, whether in your own local app or in Rails. (And I wish ConnectionPool had a bit better inline doc comments; I also have a commit in there adding a line of comments, heh.).

One lesson I learned was: don’t be afraid to write unit tests against Rails (or any other dependency) to test your assumptions.  I spent a long time trying to debug my own app, assuming the problem must be in my own code, or in my faulty understanding of how to properly use ActiveRecord under multi-threading.  Turns out, nope, it was actually a bug (or two) in ActiveRecord.  I could have saved some time if I had been willing to consider that possibility earlier — and writing some unit tests to verify that ActiveRecord is working the way you think it is/should is a great way to explore that possiblity. Of course, getting to that point still would have required me to understand how ConnectionPool works (which took quite a while), and then also figure out how to write automated tests for ConnectionPool — so maybe it wouldn’t have saved me any time, but at least I would have been on the right path.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s