Utilizing Merb threading with ActiveRecord

I stumbled into a bit of a puzzle this morning, when I discovered that there was a mutex lock in the Merb action call (dispatch.rb):

@@mutex.synchronize { controller._dispatch(action) }

What the README had to say about it:

"Merb does have a mutex lock around the call to your controller's action anywhere that you can call AR objects. Merb's lock is way smaller then rails giant lock though and allows for many more concurrent requests to be handled by one process."

This is definitely better than the "giant lock" that Rails uses, but it's still a lock. I didn't understand why it was there, as ActiveRecord is supposedly thread safe, right? Ezra pointed out that this is infact not true:

"Not only does it perform worse in thread safe 'mode' but it sometimes leaks data across threads, returning the wrong result set to a different request!"

Yikes.
You can turn off the mutex lock on the command line, which will be very useful for ORMs that are actually thread safe (Datamapper?). But until then, the lock is apparently needed to protect you from a game of Russian Roulette with ActiveRecord.

After (correctly) being grilled for claiming the lock was unnecessary, I present my self-inflicted punishment: How to utilize Merb's threading for applications using ActiveRecord.

To improve the concurrency of your Merb app, move the longer-running tasks (such as image resizing) outside of your ActiveRecord models, and outside of the lock. This frees up the process to handle other requests. Merb provides you with the tools to do this: render_deferred, and render_then_call (Described Here). These allow you to finish executing the code outside of the lock, once you know that thread safety is not a concern (in other words, when you're finished using ActiveRecord objects).

Instead of resizing images (which could take a few seconds to complete) in the model using an after_create, I'm going to instead do something similar to this:

def create
  @artist_image = ArtistImage.new(params[:artist_image])
  @artist_image.save
  id = @artist_image.id
  
  render_deferred do
    ArtistImageProc.resize_for_header(id)
  end
end

Conclusion: If you're going to do longer-running processing with Merb, handle it outside of ActiveRecord and the mutex lock on actions. If you're used to doing a fat models approach, you may have to modify your code a little bit to make sure that happens, as I did.

Apr 20, 2008 Link »

Is your login control too complicated?

Probably.

def require_login_for_special_stuff
  redirect_to(main_resource_path)
  if ((['new', 'create', 'edit', 'update', 'destroy'].include? params[:action]) && not_logged_in)
end



Mar 29, 2008 Link »

Quick and Dirty PHP Web Proxy

I've been having problems dealing with facebook's crappy nameserver support for applications. For some reason, if I use a domain in the callback, the servers go haywire and stop resolving the site. This I suppose is why so many facebook applications I've seen use straight IP addresses for the callback.

I'm tired of filing bug reports with Facebook about this, since they're obviously too busy hanging out at the beach to set their damn nameservers to reasonable refresh rates. But I need to have a domain in order to get connections fed through a web proxy, which allows me to cluster my Rails applications.

Instead of running multiple copies of my monster beast web proxy, I'm going to implement a novel solution using this ridiculously simple example code I dug out of a google search.

It uses PHP and Curl to run a basic web proxy. With a little bit of work you can have this randomize-balancing across ports. Then all you need to do is run the callback URL through this.

I could write this in Ruby, but it doesn't have real threads and probably would be pretty slow (perhaps not too slow for my usage though). The PHP guys would laugh at this, probably because they haven't figured out yet that PHP is not thread safe and probably never will be.

How do they do it then? They cheat by strapping it on to Apache. That only works because the PHP executions are completely stateless on the developer-side, which is fine until you have to do stuff like real cacheing and other stateful niceties. If you are under the illusion that PHP is fast, try running a real web application framework on top of it and watch it screech to a halt.

Pretty cool example of how you can use PHP to hack your way through dumb problems, though. I'll post the code when I finish my modifications.

Mar 20, 2008 Link »

Ten Bananas

Let me present a simplified puzzle to you.

Lets say you have ten bananas. And lets say we have ten peices of paper, called Slips, which are good for one banana each. You give them to ten people, who want to acquire bananas. The person who has the bananas can use the Slips to get oranges, and this person wants oranges.

Now, the person that created those Slips wants to make it so twenty people can buy bananas. So this person creates ten more slips, and gives them to ten more people. There are now twenty slips, each worth one banana.

Now, here's my question: Have you created more bananas by creating ten more slips?

If this logic puzzle makes sense to you, congratulations. You now know more about inflation than Federal Reserve Chairman Ben Bernake.

In this puzzle, we have doubled the size of the Slips (which is essentially a currency), but we haven't doubled the size of the goods involved, because there are still only ten bananas. If this were the real world, then the ultimate end would be that the bananas would be worth two Slips, instead of one. The effective inflation rate here would be 100%. Extremely simplified, yeah. But that's essentially how it works. Economics isn't as complicated as you might think.

Mar 05, 2008 Link »

Web 2.0 Sucks

I've recently been getting testy about the trendy nature of web development. I wanted to address some of the things about "Web 2.0" that are really starting to annoy me.

  • The fucking name
    The idea that there's a "new version of the internet" is one of the most idiotic things I've ever heard. The internet was about social collaboration when I was using it through a text web browser on a dialup connection to the fucking library BBS, you didn't change shit. There was the Well. There were Bulletin Boards, Forums, Newsgroups, Mailing Lists, IRC chat rooms, Guest Comments, and MUD servers. Sites like Facebook represent mild technology improvements to these previous collaboration systems. They do not represent a radical paradigm shift in the nature of the internet. In some cases, "Web 2.0" has actually downgraded the quality of these previous systems, which smoothly leads me into...

  • AJAX
    AJAX was that thing everybody was crazy about when it first came out as a concept. Nowadays there are two kinds of AJAX coders: people that realized overdosing on AJAX was bad and cut back, and people that flipped the fuck out and went on a giant binger with it.

    AJAX is a very useful tool when used sparingly to do things like retreive form data and do quick updates. But when you start using it to re-write the way users interface with your site, you're headed for the floor.

    For starters, AJAX is a pain in the ass to debug. Getting heavy AJAX to work on all browsers is a nightmare scenario that ultimately ends up coercing developers into knocking one of the major browsers off its "supported" list, and unfortunately for me that usually means Opera. Heavy AJAX also changes the way people expect your web site to work, which makes it annoying as hell to navigate.

    A perfect example of this is Amazon's book preview. Does this really need to use AJAX? All it does is page through a few images of a damn book. Web browsers do this perfectly already. Using AJAX here makes no sense at all, and it usually means I have to pull up Firefox to use it because it's buggy as hell.

    Really, the idea that you should release code that doesn't work on certain browsers.. think about it. Everybody should be able to use your site, regardless of the browser they're using. If you've hit the point in your AJAX where people can't even use your site, get a pot of coffee and sober the fuck up.

  • "Invite Only"
    "Fuck You". It takes a special kind of dumb to think that you can run a popular web site with a WASP country club entry policy. It's one thing if Google does this.. they have clout, they can pull it off. Chances are, you don't. Invite Only pisses people off.. it's like telling them you're too good for them. They go use your competition's program instead. You lose, like you fucking deserve to for being an asshole to them.

  • "Beta"
    Seriously, quit it. There should be two versions of a site: Pre-release, and Done. If your code is "beta", then you shouldn't release it. This is just an excuse for shitty developers to get away with releasing web sites that are riddled with bugs. And it makes your site look half-done in the process.

    You have a very small mirror of time to impress new users. If you can't, calling it "beta" isn't going to trick them into sticking around until you finally provide something useful for them. Don't quit your day job.

  • No Profit Model
    Do you build a bridge without a blueprint? In Web 2.0 you do! It's amazing how much angel money you can dig up for an idiotic idea in The Valley. Now I'm not pretending that I always write up a profitable business model. And a lot of my ideas are failures. But I always think about how a business is actually going to make money before I start developing it.

    ----
    Most of these Web 2.0 failure ideas are a strange combination of ripping off google and being dumb trust fund brats fresh out of college. I've met some very good people right out of CS, don't get me wrong. But unfortunately a large swath of them are arrogant assholes that think they're better than everybody.

    That arrogance helps them come up with words like "Web 2.0" to make it look like they reinvented the internet. WRONG. You're business as usual, with an extra heaping portion of bullshit on top. And when you come back from the Valley crying because you were a total failure, I hope you were nice to the veteran developers that saw through the fools gold rush. Otherwise you're not going to get any jobs from us and you can look forward to spending the rest of your life in your parent's basement.

    Because at the end of the day it's not about how bad you failed (because we all do at some point, it's the nature of our business). It's about how nice you were to the people around you in the process.

    Feb 09, 2008 Link »

    Arrow-right