Lojic Technologies

Archive for September 2008

Sticking With Linux For Server Deployments

leave a comment »

I recently considered switching my server deployments from Linux to FreeBSD. I need to move a number of sites off a dedicated server to either a different dedicated server (less money), or to a vps (much less money). Since I have to go through some pain with switching, I figured now was a good time to try and decide whether I should stick with Linux (Debian/Ubuntu) or move to FreeBSD.

After spending too many hours researching and experimenting (multiple installations of FreeBSD & lots of software built/installed), I’ve decided to stick with Linux for hosting web applications. Here are some advantages for each OS from my perspective.

FreeBSD Advantages

  • A slight performance advantage currently from my research, but this is debatable
  • My primary desktop is Mac OSX which is based on FreeBSD, so I would be able to leverage sysadmin knowledge between my development machine and my hosted machines. This is the same advantage I had when my main development machine was Ubuntu and I hosted apps on Ubuntu. However, OSX doesn’t require much Unix sysadmin knowledge, so this isn’t nearly as important as the analog below.
  • I like the idea of building packages from source, and the ports system does this very nicely.
  • The organization of the OS seems superior to me. The ports system, startup scripts, file locations, etc.
  • Paul Graham’s server OS of choice (at least for news.ycombinator.com), so I expect Arc will continue to be well supported on it (that is if Arc continues itself)
  • Yahoo & other large sites use it.

Linux Advantages

  • Ubuntu is a much better desktop OS, and I’ve decided to use it on my non-Mac home computers, so I can leverage sysadmin knowledge between my home machines and hosted machines. The desktop installation for Ubuntu 8.04 is unbelievably nice. If I ever become dissatisfied with OSX as my primary desktop, I’ll switch back to Ubuntu in a heartbeat. I just loaded Ubuntu 8.04 on my old 900 MHz AMD w/ 384 MB RAM, and it’s quite responsive.
  • I’ve accumulated more sysadmin knowledge for Linux than for FreeBSD, and supporting two operating systems (OSX / Linux) is more appealing than supporting three.
  • Better virtualization support
  • Linux threading seems to perform better (although FreeBSD has caught up a little)
  • Companies such as slicehost.com support Linux, but not FreeBSD (due to virtualization issues), so this limits my options with FreeBSD
  • Auto power management works out of the box – shutdown the OS and the computer powers down
  • The binary package system is much faster for installations. If I need to get another web server up and running quickly, I can do it much easier with Debian/Ubuntu than with FreeBSD.
  • Google & other large sites use it

The two operating systems seem quite close to me, and it’s possible I’ll make a different decision a year or two down the road, but for now, the cost of switching from Linux to FreeBSD is higher than any expected benefit – particularly since my code rests upon Apache, Mongrel, Ruby, Rails, etc.

I have an emotional bias toward BSD since I started out on SunOS (as far as Unix is concerned), and it seems to have a richer history; however, Debian/Ubuntu seems to be the most practical choice for me at this time.

Even though I ended up sticking with my current server platform, I do feel better about having performed my due diligence rather than continuing with a default, and I have some really great notes for setting up a FreeBSD system should I need to do so in the future 🙂

Written by Brian Adkins

September 8, 2008 at 12:18 am

Posted in software

Tagged with , ,

How to Write a Spelling Corrector in Ruby

with 16 comments

Update 10/16/2015: Please see the Racket Version also.

Peter Norvig wrote a simple spelling corrector in 20 lines of Python 2.5,
so I thought I’d see what it looks like in Ruby. Here are some areas I’m not pleased with:

  1. List comprehensions in Python made the edits1 function more elegant IMO.
  2. The boolean expression in the correct function evaluates empty sets/arrays as false in Python but not in Ruby, so I had to add the “result.empty? ? nil : result” expression to several functions. I expect there’s a better way to handle this also.

Otherwise, the translation was pretty straightforward.

Here’s a link to Norvig’s page:

That page includes a link to a text file that I saved locally as
holmes.txt: http://www.norvig.com/holmes.txt

def words text

def train features
  model = Hash.new(1)
  features.each {|f| model[f] += 1 }
  return model

NWORDS = train(words(File.new('holmes.txt').read))
LETTERS = ("a".."z").to_a.join

def edits1 word
  n = word.length
  deletion = (0...n).collect {|i| word[0...i]+word[i+1..-1] }
  transposition = (0...n-1).collect {|i| word[0...i]+word[i+1,1]+word[i,1]+word[i+2..-1] }
  alteration = []
  n.times {|i| LETTERS.each_byte {|l| alteration << word[0...i]+l.chr+word[i+1..-1] } }
  insertion = []
  (n+1).times {|i| LETTERS.each_byte {|l| insertion << word[0...i]+l.chr+word[i..-1] } }
  result = deletion + transposition + alteration + insertion
  result.empty? ? nil : result

def known_edits2 word
  result = []
  edits1(word).each {|e1| edits1(e1).each {|e2| result << e2 if NWORDS.has_key?(e2) }}
  result.empty? ? nil : result

def known words
  result = words.find_all {|w| NWORDS.has_key?(w) }
  result.empty? ? nil : result

def correct word
  (known([word]) or known(edits1(word)) or known_edits2(word) or
    [word]).max {|a,b| NWORDS[a] <=> NWORDS[b] }

After you’ve saved the holmes.txt file, load the code into irb and call the correct function with a string as follows:

badkins:~/sync/code/ruby$ irb
irb(main):001:0> require 'spelling_corrector.rb'
=> true
irb(main):002:0> correct "whree"
=> "where"

Written by Brian Adkins

September 4, 2008 at 3:58 pm

Posted in people, programming

Tagged with ,

Ubuntu Linux 8.04 – Wake on LAN

with 3 comments

Now that I’ve switched to a Macbook Pro with OSX Leopard as my primary desktop, I’ve located my Ubuntu machine in another part of the house to be accessible to my children. Not wanting to walk to the room where it’s located just to flip the power switch, I researched how to get “wake on LAN” working, so I could power it up remotely.

1. Enable the appropriate setting in your BIOS. Mine had something to do with wake on PCI device.

2. Install ethtool if you don’t already have it.

sudo apt-get install ethtool
cd /etc/init.d
sudo vim wakeonlanconfig

Add the following lines to that file:

ethtool -s eth0 wol g

Install the script:

sudo update-rc.d -f wakeonlanconfig defaults

Run the script:

sudo /etc/init.d/wakeonlanconfig

3. Keep the network interface alive after shut down.

sudo vim /etc/init.d/halt

Change the following line:

halt -d -f -i $poweroff $hddown

to the following line (i.e. remove the -i)

halt -d -f $poweroff $hddown

4. Get the MAC address

ifconfig | grep HW

5. Send the magic packet via the following Ruby program:

require 'socket'
mac_addr = "x21x53x39xB3x90x42"
s = UDPSocket.new
s.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
s.send("xff"*6 + mac_addr*16, Socket::SO_BROADCAST, '', 7)

Written by Brian Adkins

September 3, 2008 at 12:23 am