Today I was working on some revisions to Twitter’s Protected User stack { or Project: PrivateParts as I like to refer to it in my head }, when I had to make some string changes to emails being sent to users. Offhandedly, I ran across this bug report on RubyForge.
HOLY HELL IN A HANDBASKET!
The Ruby GetText 1.90.0 gem uses an instance of a Class Object as a key to a hash! Steven Rusitschka noticed this and noted that “the memory Mongrel used increased by 1 MB with each request it served …”
To avoid any possibility of a reader absentmindedly skipping over that last quote from Steven, I present it for you again in vibrant color and with extra bold.
“the memory Mongrel used increased by 1 MB with each request it served …”
Okay. Deep breaths. Before everyone goes around MonkeyPatching GetText, there’s a new release out, 1.91.0. Let’s look and see if a fix has been put into place.
Old: 1.90.0
def bound_target(klass = self) # :nodoc:
if cached?
if @@__cache_bound_target[klass] # <---- Yowza!
return @@__cache_bound_target[klass]
end
end
ret = nil
if klass.kind_of? Class or klass.kind_of? Module
ret = klass
else
ret = klass.class
end
ret = GetText if ret.name =~ /^\#<|^$/
@@__cache_bound_target[klass] = ret
ret
end
New: 1.91.0
def bound_target(klass = self) # :nodoc:
id = klass.object_id
if cached?
tgt = @@__cache_bound_target[id] # <---- Ahhh, much better.
return tgt if tgt
end
ret = (klass.kind_of? Module) ? klass : klass.class
if ret.name =~ /^\#<|^$/ or ret == GetText
#GC for dead object_ids.
ret = Object
if @@__cache_bound_target.size > CACHE_BOUND_TARGET_MAX_SIZE
@@__cache_bound_target.clear
end
end
@@__cache_bound_target[id] = ret
ret
end
The GetText gem is now using the object_id as the cache key. To say the least, this has made a huge difference in the memory profile of Twitter’s Mongrels. Not much more to say here. If you’re running GetText with Rails and are find yourself a bit leaky, check your gem version. You may be due for an upgrade!
Oh my. Are there any good standard ruby libraries?
To be fair, this isn’t a standard library.
Ian (and I say this as someone who loves the Ruby language and uses it almost primarily) the vast majority of Ruby’s core and stdlib libraries are really poorly designed and not worthy to be included with the language. The core and stlib are pretty bloated, and at least 80% of the libraries in those packages are rarely used by Ruby programmers. Most of the good stuff is available in external libraries available on github and rubyforge.
IMHO Ruby needs to remove almost all of its core libraries (aside from the very basic primitives) and decentralize the development process a bit. For example we’d have alot higher quality Net (protocol) and Date (date/time) libraries if we did this.