Rails caching + Phusion Passenger Smart Spawning

If your web app runs on Rails and you deploy with Phusion Passenger, you are probably aware of the issues inherent in smart spawning. When smart spawning is on, each new spawned process shares file descriptors with the parent process. This means that if your app has a persistent connection to a server (say, memcached), whenever Passenger spawns off another instance you HAVE to close and reopen any connections.

If you use Rails’ integrated MemCacheStore support for memcached, there isn’t a “clean” way to reset the connection. Your two solutions are either to monkey patch ActiveSupport::Cache::MemCacheStore or to use instance_variable_get to access the underlying memcache object. The latter solution is slightly cleaner than the first (I suppose…) so I’ll run you through it.

First of all, in config/environment.rb, let’s add the boilerplate code to register a block to be executed when a new worker process is spawned:

if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    if forked
      # Magic goes here
    else
      # No need to do anything.
    end
  end
end

You should already be familiar with that from the Passenger docs, but I include it for completeness. What we really need is the magic line that goes in that block to reset Rails’ connection to memcache. That line is:

Rails.cache.instance_variable_get(:@data).reset if Rails.cache.class == ActiveSupport::Cache::MemCacheStore

Just pop that in under

if forked

and it will take care of resetting the memcache connection for you. Why does this work? The @data instance variable is the memcache connection object in MemCacheStore. It has a reset method. instance_variable_get is a method that will return instance variables even if there isn’t an accessor for them. Pretty simple!

I’ve submitted a patch to the Rails team, and hopefully they will deem it fit to be added into Rails. If they do, Rails.cache.reset will be all you have to put there! It does have flaws — if they change the implementation of the MemCacheStore class, this line will have to be changed as well. But until a true reset method is added, this is probably the best solution.

Putting Your Nose to the Grindstone

Let me give you some background information before I delve into the meat and potatoes: Since this time 2 years ago, I haven’t had more than 2 weeks off of school or work. Now, don’t interpret that the wrong way and say, “Eric, you’re a total wuss. There’s people out there who only get a week off every year.” I understand that having as many breaks as I do is a very wonderful, joyous thing, and I’m not complaining about it. I do, though, think that every once in a while you have to take more than a week or two off. It lets you disconnect from your work for a little while and rest your mind — a break that lasts less than a week or two just doesn’t have the same mentally-unwinding effect. So, now that I have a nice 1 month block of time off for the first time in two years, I thought that what I’d spend most of my time doing would be playing video games or guitar, or just vegging out in front of the TV.

What I found, though, is that wasn’t the case at all. Read the rest of this entry »

Game Update and a Random Observation

Keyframe animation was done Saturday, and I took a break from coding Sunday. Today my plan is to begin gluing Box2D to the rest of the game, which should basically take the project from “tech demo” to “actual game.” Hopefully I won’t run into many snags during the process. I don’t think I will because the python bindings for Box2D are very clear, but I’ve never worked with Box2D before.

In other news, I was reading Jeff Atwood’s Coding Horror blog, and I happened upon this article. I’m not even a college graduate yet, but I was able to write the FizzBuzz test program he mentioned in less than a minute. Now, I don’t think that’s a particularly amazing task, and anyone worth their salt could pull it off in as much if not less time, but I simply find it scary that such a simple task could take someone with the title of “Senior Programmer” 10-15 minutes to complete! It scares me that I could end up having someone who knows less than me be my boss, especially in a programming job!  I don’t know if I could keep my faith in humanity if I had to spend months and years of my life reporting to a guy who doesn’t know what modulo is.

First Real Post!

So, I’ve been working on several things lately. Here’s a list:

  • I recently entered the uDevGames competition for this year. My entry is a game called Run, Stickman, Run! and it’s going to be a hybrid of a 2D shooter like Geometry Wars and a platformer like Super Mario. I’m working in Python, because: a. I need the development time speedup more than the extra performance of languages like C++, and b. there’s a lot of great frameworks like pyglet for Python that let me work on real problems rather than the ones that have already been solved. The main gameplay gimmick (and no, I won’t hesitiate to call it that) is that your character is always running forward in the level, which should increase pressure on the player and encourage a feeling of speed. Here’s the main character:stickmanCurrently, I’m finishing up the keyframe animation system I’ve designed, which operates by simply attaching “limbs,” or sprites, to other limbs. In this way, animation is easily created from just rotational values, which are easily interpolated. Hopefully this system will allow me to create great-looking animation without having to resort to frame-by-frame sprite creation, which I have neither the skill nor patience for. I still have a lot of work to do on the game, but I also have a lot of remaining time. You can follow the development effort at my official uDevGames developer diary, here.
  • In my free time I’ve been reading through Code Complete 2 and the OpenGL SuperBible. Both are really awesome books.
  • As of the end of this semester, I’ve completed the first part of my latest research with my advisor/mentor at BU. I now have an application which allows me to pull statistics from machine traces, and it outputs those statistics into the .arff file format that Weka uses. This allows me to cluster machines, into any given number of clusters, and then use those clusters to do several things:
    • Use those clusters as a source for any number of simulated machine traces, which increases the accuracy of the simulation.
    • Test existing schedulers on each of the clusters to see which types of machines they perform best on — and even write new schedulers that exploit features of the clusters.
    • Use the clusters to classify grids by determining what percentage of machines fit into each cluster, as compared to other grids.

The cool thing is that I did the whole application using PyObjC, so there’s a separation of interface (which only works on my Mac, ’cause it’s Cocoa) and implementation (which could easily be reused for a command-line version on any operating system that supports Python). And with Python’s processing, it was easy to multi-thread the application, multiplying the speed of the stat computation by the number of processors. The upshot is that it was great practice for both GUI coding and multi-threading, and that it has set me up well for my continuing research next semester.

I have a lot of stuff on my plate at the moment, but I want to keep this blog updated more often so I have a record of the stuff I’ve done in slightly more detail than twitter affords. So, check back soon if you’re interested.

New blog, new site.

So here’s my new blog… pretty spiffy. Hope to keep track of everything I do here, as well as any interesting stuff I should happen to happen upon. Cool.