Why I am not using Masochism for my master-slave setups and why monkey-patching isn’t the only solution

I got a message this morning from Gregg at Ruby5 asking why I wrote the master_slave_adapter plugin instead of using Technoweenie’s Masochism and I think the answer to this question deserves a little blog post (and the blog really needs some new content :P).

When building the Talkies project we had to setup a master-slave environment using MySQL at the production servers. To get these things up and running I configured the replication on MySQL and set out to find a solution on Rails/ActiveRecord to handle this special need, all SELECT* statements should be sent to the slave db while all other commands should be sent to the master. The only solution available at the time was Masochism (at least it was the only one I could find).

With Rails 2.1, everything looked like we would live happily ever after, but Rails 2.2 brought a lot of changes and many of them on ActiveRecord, the main one being connection pooling and we upgraded. The production server, that wasn’t really live yet, broke badly, the new connection pooling code made the application crazy and the slave was receiving UPDATE* and INSERT* calls ( this was the code at the moment ).

With this new issue showing up I set out to find a solution, the first thing was to hack the plugin itself (as github had no “issues” thing at the moment). Trying it out I couldn’t really find a simple fix and wasn’t really happy with the way the plugin worked, looked a lot like a hack when a hack wasn’t really needed, so I started to write my own solution.

The first requirement was that it should perform no black magic at all, we were burned more than once during the project by plugins that were too clever and relied heavily on monkey-patching, so my solution had to be really straightforward and do as little clever things as possible.

But hey, active_record needs a database adapter, so why not just build a fake database adapter that forwarded the work to a master or slave connection depending on the method called? This way I would never need to hack ActiveRecord, as the thing would just be a common database adapter, like all the others and the plugin would survive to Rails upgrades with little or no changes. And that’s exactly what I did, an ActiveRecord database adapter who’s job is to route method calls to a real master or slave connection.

Why was it an improvement?

By relying on the ActiveRecord database adapter contract I had no need to monkey-patch Rails itself, it would just work, even if Rails or ActiveRecord got upgraded, the only thing that would make me change the plugin was if the database adapter contract got changed and this isn’t really something that changes a lot.

And if there’s one thing that’s burning a lot of people using plugins and Rails itself is clever code and too much monkey-patching. When you’re building a solution that’s going to be “inserted” inside someone else’s codebase that you don’t even know how it’s going to look like, you better try to avoid changing too many things or breaking well known contracts, you might end up with bugs that are hard to discover and kill. And they’ll surely make you waste a lot of your time.

Monkey-patching and class-redefinition are some of the coolest features of Ruby as a language, but they should be used with care and are better avoided if possible.

13 Responses to “Why I am not using Masochism for my master-slave setups and why monkey-patching isn’t the only solution”

  1. Apie Says:

    Sounds good – enjoyed the post. Nicely argued aswell. When the need arises I will look here for a solution. :)

  2. John Says:

    Is there any legacy plugin from technoweenie which as not being replaced by a far better one ? :P

    • Maurício Linhares Says:

      I still find attachment_fu the best solution for attachments :)

      • Jack Harkness Says:

        Really! Why don’t you like about Paperclip?

        • Maurício Linhares Says:

          S3 and Cloudfront support :)

          • rick Says:

            Of if I’m not mistaken, you added cloudfront support, right? Your name sounds very familiar :) I replaced my own legacy plugin actually… the rewrite branch of attachment_fu kicks much more ass. I’ve literally been using it for about a year and a half, but it’s been hiding in a non-master branch because I haven’t had time to write decent docs for it.

    • rick Says:

      Why didn’t you just submit the code to masochism? I’d take a full rewrite (it’s a tiny plugin anyway), and then everyone can benefit. Plus, you get more users using your code that can point out problems.

      The masochism plugin is kind of funny. I wrote it as a joke in response to some other weird master/slave plugin. I’ve never really used it though, but all these other people say it rocks and sent me lots of fixes. *shrug*

      • Maurício Linhares Says:

        Hey Rick,

        Well, I didn’t submit ‘cos it was “another” plugin. I never thought that you’d accept it as a “replacement” ;D

        • rick Says:

          Ah I realize it can be a tough call to make. You’d have to either support the masochism’s API pretty closely or provide a good migration path. Not trying to start some shit or anything :)

  3. Sebastian Says:

    Heh… I guess independent reinvention of the wheel is the best confirmation that your thoughts were on the right track.

    http://github.com/sd/master_slave_adapter/tree/master

    I should have promoted it better.

  4. Rails Slave Database Plugin Comparison | Relentless Simplicity :: The Bonanzle Tech Blog Says:

    [...] The author himself has admitted (in comments) that the project has fallen into a bit of a state of disrepair, and apparently it [...]

  5. Maurício Linhares Says:

    Now I don’t remember it either. I did integrate Cloudfront to attachment_fu but right now I’m not really sure if I handled it back to the project, it’s been a long time since I did it.

    But anyway, I’m still using attachment_fu a lot and will definitely look into your new branch, maybe I can contribute with the docs that are not there yet, the plugin helped me a lot, maybe it’s time to give something back.

  6. rick Says:

    That’s cool.. I also have some s3/image handling features to push up too. My github message queue is insane. I’ve kind of been taking a break from the OSS scene this year if you can tell…


Leave a Reply