Massive memory leak in ruby-gettext 1.90.0 0
Meetings 0
Side project: De TV Flat (KRO) 1
My first Rails 2.0.x project has been running in production for a couple of months now. It's the website for KRO's "De TV Flat", a children/teens program airing every Saturday on dutch national television around 9am (channel Nederland 3) untill the beginning of summer. I'm very proud to actually get one of my projects on TV! The premise is basically "Youtube for kids" with the chance of getting your self-made video's broadcasted on TV!
I really like the instructional video's made by the TVFlat crew, very helpfull tips for creating your own video content.
Technology used:- Linux
- Nginx HTTP server
- Mongrel
- MogileFS clustered storage
- Rails 2.0.2
- Merb 0.54 for critical code paths, beats Rails to a pulp when it comes to roundtrip times
- Memcached
- MySQL
- Lucene
- mplayer / ffmpeg / faac for transcoding, direct broadcast quality feeds are generated!
- Flash video
Hope I can find some time later on to write a bit about the different parts.. anyway, go check it out!
A baby girl!!! 4
It has been very quiet on this blog, but not so much here at home. On March 2nd 2008 our daughter Mia Morena Elisabeth Lo-A-Foe was born.
Mia is a healthy baby girl who regularly eats every 3 hours, around the clock. After 6 weeks we're completely comfortable with the new schedule. Andrew loves his baby sister very much but still pokes here once in a while just to see what's she's made of :)
has_many_polymorphs tagging snafu 0
P.S. Better late than never: Happy 2008!!!
JRuby saves the day 0
So I'm rewriting yet another subsystem which consists of a mismash of several languages and programmer ego's (hardcore C being the largest one, aargh) to what else .. Ruby. Everythings going smoothly. Every line of Ruby code replaces about 10 lines of "put other language here" cruft. Life couldn't be more beautiful. But then I hit the wall, the Java wall. Here I'm confronted with a full enterprisy Service Manager complete with dependencies on Java-only libs. Now what? I could rewrite the whole thing in Ruby. But then there would be 2 implementations of the same thing to maintain, not to mention reading through Java code, bad.
Enter JRuby. Since the main code blob of this project is captured in a Mongrel plugin I thought about just deploying the whole of Mongrel on JRuby. Unfortunately JRuby Mongrel support was not there yet (Mongrel 1.1 supports JRuby). So the next best thing was to build some kind bridge between JRuby and Ruby + Mongrel + Plugin. Distributed Ruby (DRb) is a perfect fit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# # server.rb (this) # jars/big-bad-service.jar # APP_ROOT = File.join(File.dirname(__FILE__), '.') require 'java' require 'drb' require "#{APP_ROOT}/jars/big-bad-service.jar" BigBadService = com.blah.BigBadService class JRubyServer def initialize @bbs = BigBadService.new @bbs.initialize_service end def bbs_call(param) @bbs.bbs_call(param) end end if __FILE__ == $0 DRb.start_service 'druby://127.0.0.1:6666', JRubyServer.new DRb.thread.join end |
Execute like ruby server.rb, and then you'll have the server listening on port 6666 of localhost. Nice, we can now call our Java service from other Ruby code with this simple snippet:
1 2 3 4 5 6 |
require 'drb' DRb.start_service java_bbs = DRbObject.new(nil, 'druby://127.0.0.1:6666') puts java_bbs.bbs_call("Whack!") #=> "Whacked!" |
Kewl! Except for one big caveat. As of JRuby 1.0.x Java objects cannot be marshalled correctly so passing them to your Ruby code will cause all sorts of interesting hangs and crashes when you access them concurrently (see JRUBY-1235). Untill JRuby 1.1 is out you can synchronize all your calls to JRuby and making sure you convert any results to proper Ruby objects before using them elsewhere in your Ruby code.
This hack saved me loads of (Java hacking) time!
GMail expanded
Keeping things in perspective
NuSOAP together with PHP5-SOAP
Cannot redeclare class soapclient
Both NuSOAP and PHP's SOAP use the same class name for the client implementation. Instead of uninstalling Feisty's PHP module and rolling my own I decided to simply patch the NuSOAP 0.7.2 .php file and rename the class to nusoapclient. Saves a boatload of time IMHO. Patch to NuSOAP 0.7.2
Torturing Ruby (and laughing at your own code) 10
While cleaning up some code I ran across some obscure code of mine from my Ruby youth. I remembered reading about an ultra cool Ruby tool the other day so I decided to give my code a good flogging. The victim for tonight is a method used to slice ID numbers into chunks of at most 4 characters long. This is required to overcome the typical Linux file system limitation of at most 32000 entries per directory. In this case the project stores roughly a million thumbnail images on disk. We start with the original piece of code:
1 2 3 4 5 6 7 8 |
def splice_number(number, part_size = 4) n = number.to_s r = [] return r if n.size.zero? (n.size / part_size).times { |t| r << n[(t*part_size)..((t+1)*part_size-1)] } r << n[-(n.size % part_size)..n.size] if (n.size % part_size) > 0 r end |
Ah yes, WTF was I thinking when I wrote this? Who cares, it seemed very clever then! What does Flog think about this?
Total score = 28.35
none#splice_number: (28)
7: size
3: *
2: %
2: []
2: <<
1: +
1: -@
1: -
1: /
1: lit_fixnum
1: zero?
1: >
1: to_s
1: times
Pretty good score. Now it’s time for some torturing. Say hello to my little friend: unpack!
1 2 3 4 |
def splice_number(number, part_size = 4) n = number.to_s n.unpack("a#{part_size}" * (n.size / part_size) + ((n.size % part_size == 0) ? "" : "a*")) end |
Flog?
Total score = 13.05
none#splice_number: (13)
3: size
1: %
1: /
1: ==
1: *
1: +
1: to_s
1: unpack
0: lit_fixnum
Yeow, well over half the pain gone!! Perhaps we can still improve by being less clever?
1 2 3 4 5 6 |
def splice_number(number, part_size = 4) n = number.to_s r = n.unpack("a#{part_size}" * (n.size / part_size) + "a*") r.delete("") r end |
More lines, but less code! Hmm?
Total score = 9.25
none#splice_number: (9)
1: size
1: /
1: *
1: +
1: delete
1: to_s
1: unpack
0: lit_fixnum
Weeh, a full 2/3 of the pain flogged out of the code! That’s all the torture I’ll do for tonight..
Update: Okay, couldn’t help myself, last blow:
1 2 3 4 5 6 7 8 |
def splice_number(number, part_size = 4) n = number.to_s p = "a#{part_size}" t = n.size / part_size r = n.unpack(p * t + "a*") r.delete("") r end |
Total score = 8.05
none#splice_number: (8)
1: *
1: size
1: +
1: delete
1: to_s
1: /
1: unpack
0: lit_fixnum
Done..
Old new job
Firmware update gone south 3
A quick Google search showed up quite a few posts of people in the exact same predicament as me! However, not a single post offered any sane fix other than bringing the Mac in for repairs, if you were lucky enough to have it under warranty or had AppleCare. Aargh!! Oh well, got nothing to loose so I called Apple Benelux and explained my situation. The kind person on the other side suggested I bring in the machine to an authorized dealer to check it out. Okay, so I brought it to RAF Amsterdam, which is the closest Apple authorized repair service to me. 3 weeks and a lot of calls to RAF later (apparantly their Mac guy went on vacation and they forgot to mention that during the intake) I finally got the verdict, new superdrive required, price tag: €410,- @#$@!!@#$%??!!!! That's got to be the most expensive DVD burner on the planet!
I called Apple again explaining them I was really upset I had to dish out this much money to fix a problem that was clearly caused by not properly testing their update procedure. I mean how hard is it to detect and stop a reboot in a firmware updater?? Firefox annoyingly stops reboots all the time, so a piece of Apple software should definitely be able to do this do. "I understand sir, let me talk to the tech people.. please hold..".. 2 minutes later: "Sir, we have OK'd this repair under warranty..".. WOAAH!!!
One week later I picked up my Macbook Pro, new superdrive installed, everything working. Charge: € 0,00!!
Big kudo's to the Apple Customer Satisfaction department!! That was 2 weeks ago.. It must be said though that a lot of folks around the world did not have this much luck with Apple. As of today there is also not a single official word from Apple regarding this issue, the firmware update was silently pulled from Apple's website and all traces of it have disappeared.
Forum thread 1: Superdrive update 2.1 killed my drive.
Forum thread 2: Superdrive Update 2.1 killed drive.
Still keeping an eye on how Apple handles this...