iPhone 3G secured.. the wait starts 2
Rails' end_of_month fixed
Getting XS4ALL HSDPA/UMTS working on OS X Leopard 8
Last week I received my HSDPA/UMTS/GPRS card from XS4ALL. After the major ADSL outtage fiasco It really dawned on me that not having net access for a day actually costs more than the whole wireless plan per month! Think about it, as I telecommute 4 days in the week I would actually have to drive to the office to get work done (luckily our offices were spared from the outtage!), the parking money alone is almost more than the whole plan (go Amsterdam!). Enough justification for the new toy. It arrrived, weeh!
The specs clearly state it should work fine an OS X 10.3.x or later. Unfortunatly the instructions from XS4ALL are completely useless when you are running on Leopard. It probably has more to do with Option and their drivers or OS X and its (shoddy) support for the hardware which is the Globetrotter Express 7.2 card btw.
After 2 hours of fiddling with various releases of drivers and trying all the the blog tricks from people around the world with the same card I was almost ready to give up when I stumbled upon this HOWTO for Linux. As always Linux to the rescue. It turns out the card is basically just a glorified modem and you just need the right AT commands and some pppd magic to get things going.. Grrrreat, familiar territory! (I have to confess, OS X dumbs you down, so having things breaking once in a while is gooooood!!)
After some searching I found the following devices:

Cool, connecting to the cu.GT HSDPA Modem tty device should work:
$ screen /dev/cu.GT\ HSDPA\ Modem
AT<return>
OK
Yes! The device is alive. Now, to find out if there is some combination of settings in the Network Preferences that actually make it work. Some further blogging shows that the Option » GSM configurations comes closest to what this cards expects.
Wow, 5 entries for the card. Just pick one which gives you a modem icon. Then choose "Advanced..." and pick model "Option" and then choose "GSM" (should be the only option anyway). In the "APN" field you should fill in "umts.xs4all.nl".
Back to the connection setup screen. Fill in "*99***1#" in the Telephone number field, although this is not strictly needed I think. Fill in your XS4ALL username and password in the field. Note: even though XS4ALL states you don't need your account password to connect at least I had to fill in the correct password. The pppd connection would immediately be dropped otherwise. Also, select the "Show modem status in menu bar" for convenience.
Now it's time to connect. Select the "Connect Globetrotter HSDPA Modem" from the dropdown modem menu bar. You should see the modem connecting..
You can open up the console and monitor "system.log" and also filter on "pppd" to see the relevant lines
If everything went well you should now be connected to the Internet and have an IP address in the mobile.xs4all.nl range. Enjoy! I have the Mobile start plan which currently gives you 768/128 and I'm happy to say that from all the locations I've tried so far in and around Amsterdam I always get the full bandwidth. Ping times are also quite reasonable, most of the time around 90ms, sometimes in the 300ms range (perhaps when it drops back to GPRS?). Anyway, SSH and web browsing are perfectly doable. Next up.. OpenVPN setup... another day..
Update: Forgot to mention this, but you need to disable the PIN on your SIM card for all of this to work. You can do this by putting it in your mobile phone and disable it using the phone's config menus.
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