2015-05-07

2010-03-25

New fb Release

The last release of the Firebird Ruby extension fb for Windows was 0.5.3. Back then, binary gems seemed to be more common than they are today. The One-Click Installer for Ruby 1.8.6 had taken the lead from the Cygwin-based versions that came before, due to better compatibility with various Windows libraries and a smaller footprint.

Building Ruby extensions required using the same version of MSVC that had been used to build Ruby and another compiler could not be substituted, because numerous bug fixes and workarounds for Windows were specific to that one compiler. Building the Firebird extension required three different options to specify the location of various libraries, which in the tradition of Windows, had no standardized locations.

The workstation with the magical combination of build tools and libraries has long been retired, so while the Unix version of the extension has seen bug fixes and improvements, the Windows version has languished. It was generally good enough for development and small utilities, though and since my company deploys on Linux servers, there was no strong incentive to invest in a solution. But I always felt bad for the Windows users left out in the cold.

I'm happy to say that the RubyInstaller Team has done great work with MinGW32-based build of Ruby 1.8.7 and the associated DevKit. It only took a couple tweeks to extconf.rb to recognize the mingw32 platform along with mswin32 and then everything "just worked." Well, almost. You still had to build by hand, specifying --with-opt-dir=C:/Progra~1/Firebird/Firebird_2_1 (or wherever your Firebird installation was). To make gem installs work better, it now looks in C:\Program Files\Firebird for the latest version of Firebird and uses that one. Suggestions for improving this logic to work with foreign language versions of Windows are solicited.

In a more-perfect world, every Windows machine might come with a proper development toolchain, but for now you'll need to install DevKit in the proper location and have Ruby's bin directory in your PATH.

fb-0.6.6, with the latest tweaks, is on RubyGems.org and github.

UPDATE: fb-0.6.7 with improved installation for non-English Windows versions is out.

2010-01-31

Marshalling MongoMapper Documents

Conventional wisdom has it you shouldn't store models in your Rails sessions. Conventional wisdom is right: Marshalling complex objects can be slow; Session objects can become stale; Sessions can balloon up too large for cookie storage, limiting your scaling options.

However, the rule that models don't belong in the session is trumped by the rules that POSTs should yield GETs and GETs should not mutate state. Every page should be reloadable, without an annoying pop-up asking if you want to resubmit a form. POSTs are allowed to be dangerous. POSTs are allow to charge your credit card, delete records or log you out. So, when creating or editing a model, if the model fails to validate, I refuse to display an error page as a direct result of a POST. Instead, the user's browser is redirected back to the new or edit page they were on and the form is redisplayed with helpful error messages. Indeed, this has become a standard Rails pattern.

Which brings us to my most-recent roadblock. MongoDB is my new favorite toy and MongoMapper is a promising stand-in for ActiveRecord. However, when I employed this standard Rails pattern:
def new
@user = flash[:user] || User.new
end

def create
@user = User.new params[:user]
if @user.save
redirect_to user_path(@user)
else
flash[:user] = @user
redirect_to new_user_path
end
end
I was stymied by this error:
TypeError: singleton can't be dumped
Some chain of references from the model evidently connects it to a singleton object. MongoMapper is still under heavy development, so I'm confident at some point this will be resolved, but meanwhile the following monkey patch appears to do the trick:
module MongoMapper
module Document
def marshal_dump
instance_variable_names.inject({}) { |m, name| m[name] = instance_variable_get(name); m }
end

def marshal_load(values)
values.each_pair { |k, v| instance_variable_set(k, v) }
end
end
end
I stuck this code in a file called mongo_marshalling.rb in config/initializers.

2009-12-07

Workstation NFS Mounts Considered Evil

The symptom: Connections to the Firebird database on my MacBook Pro were taking 20 seconds. Every time.

It wasn't always thus.

It didn't matter which client I used: isql, Ruby, FlameRobin. It didn't matter if I connected from the local machine or a different workstation.

I tried installing various builds: Superserver, Classic, 64-bit and the experimental 32/64-bit build.

I used dtruss (that's an strace-like interface to dtrace for the Mac) on isql to see where it was hanging.

I watched CPU and memory and network usage.

Finally I installed Wireshark and started watching network traffic while connecting to the database. There it was. Every time, while waiting for the client to connect to the database, there was a flurry of mdns packets.

mdns? Multicast DNS. What Apple started calling Bonjour right after Tibco Software beat them to the Rendezvous.

Those flurry of packets were all attempting to lookup alpha.local. Alpha was the name of a CentOS test VM I occasionally ran in VMware Fusion. Evidently I was only allowed to connect to Firebird after first trying to resolve alpha.local (and timing out) a few times. I tried putting alpha.local in /etc/hosts. That lengthened connection times to a minute and a half or so.

Starting up the VM caused the name to resolve quickly and my Firebird connections to proceed at full speed. Shutting down the VM reverted connection times to 20 seconds again.

I nuked the VM from VMware. Still no dice.

Grepping around in various DNS-related files for alpha.local, I found the clue I needed. A forgotten NFS mount I had once used to edit a website on the VM using TextMate.

Disk Utility -> File -> NFS Mounts. Kill it. Dead. All better!

Firebird enumerates NFS mounts to ensure the database being attached does not reside on a network share, because NFS file locking is unreliable.

Next time I think I'll use Transmit if I must edit the site with TextMate. Otherwise I'll just use Vim.

2008-11-23

FitTimer

A few days ago, we released our second iPhone application, titled FitTimer. It helps you get the most out of the time you spend in the gym by tracking how much time you actually spend exercising and helping you limit the amount of time you spend on breaks.

Find it in the App Store.

FitTimer main screen paused.FitTimer Timer Setup Screen.

FitTimer Timer Summary Screen.FitTimer Settings Screen.

2008-10-21

Chess Clock for iPhone

I've been remiss in not mentioning that my first iPhone app has finally appeared in the App Store. iChessClock is a simple and attractive Chess Clock for the iPhone and iPod touch.

Ready/Paused



In Play (white to move)



Time Expired



Setup Screen


2008-04-27

Looking for the Mouse

Great article by Clay Shirky.

I avoided Twitter for a long time, thinking it was the level of hell below Facebook. I gave it a second look because some guys I respect said they were on it.

After nearly three weeks, my conclusion is that yes, it is another time sink and source of interruptions, joining e-mail, IM’s and blogs, and yes there is a certain amount of drivel, like “I’m eating a cheese sandwich.” But, it’s an interactive time sink and the people I follow are, for the most part, interesting people doing interesting things. Their default activity is not sitting on the couch watching the boob tube. They are traveling, writing code, making presentations at conferences and user groups, taking pictures, playing chess, reading interesting articles and sharing them.

Of course there have always been people who never went into a TV stupor. My parents didn’t have a TV when I was growing up, forcing me outdoors during the day and into books at night, but the common understanding was that I was deprived—disconnected from The Source of popular culture. Now, the feeling is that TV is tired and it is the alternate activities that are hip.