Archive for the ‘Software’ Category

Redis rocks!

Posted on November 5th, 2009 in Databases, Linux, Mac, Open Source, Opinion, Programming, Software | Comments

In my development blog, I previously wrote that MongoDB was the future of database storage. I might reconsider my decision, now that I’ve discovered Redis. In a nutshell, Redis is a key-value store. But it’s not a simple key-value database, as it has lots of commands and extra goodies, such as file persistence (so data can be stored from memory to a file, and restored in case of failure) and awesome data structures like lists (with push / pop) and sets (even ordered sets). Besides that, Redis boasts atomicity and even master-slave replication. It’s quite a lot of stuff for a lean package.

One of the things I love the most about Redis is it’s speed. Believe me, this little database is fast. Redis includes a benchmark tool, so I ran the default benchmark (Approximately 10,000 total requests per command, from 50 simultaneous clients) just to demonstrate its raw speed. These tests were run on a Mac Mini (1.83 GHz Intel Core 2 Duo, 2 GB RAM) under Ubuntu 9.10 Server:


dennmart@ubuntu:~$ redis-benchmark
====== SET ======
10005 requests completed in 0.14 seconds
50 parallel clients
3 bytes payload
keep alive: 1

34.89% <= 0 milliseconds
99.19% <= 1 milliseconds
100.00% <= 2 milliseconds
74111.11 requests per second

====== GET ======
10003 requests completed in 0.13 seconds
50 parallel clients
3 bytes payload
keep alive: 1

34.62% <= 0 milliseconds
99.79% <= 1 milliseconds
99.83% <= 2 milliseconds
99.87% <= 3 milliseconds
99.91% <= 4 milliseconds
99.94% <= 5 milliseconds
99.97% <= 6 milliseconds
99.99% <= 7 milliseconds
100.00% <= 8 milliseconds
74649.25 requests per second

====== INCR ======
10005 requests completed in 0.15 seconds
50 parallel clients
3 bytes payload
keep alive: 1

25.60% <= 0 milliseconds
99.73% <= 1 milliseconds
99.80% <= 2 milliseconds
99.83% <= 3 milliseconds
99.86% <= 4 milliseconds
99.89% <= 5 milliseconds
99.92% <= 6 milliseconds
99.95% <= 7 milliseconds
99.97% <= 8 milliseconds
100.00% <= 9 milliseconds
65392.16 requests per second

====== LPUSH ======
10001 requests completed in 0.13 seconds
50 parallel clients
3 bytes payload
keep alive: 1

37.62% <= 0 milliseconds
99.78% <= 1 milliseconds
99.82% <= 2 milliseconds
99.86% <= 3 milliseconds
99.89% <= 4 milliseconds
99.93% <= 5 milliseconds
99.96% <= 6 milliseconds
99.99% <= 7 milliseconds
100.00% <= 8 milliseconds
77527.13 requests per second

====== LPOP ======
10000 requests completed in 0.14 seconds
50 parallel clients
3 bytes payload
keep alive: 1

34.13% <= 0 milliseconds
99.69% <= 1 milliseconds
99.82% <= 2 milliseconds
99.86% <= 3 milliseconds
99.90% <= 4 milliseconds
99.93% <= 5 milliseconds
99.96% <= 6 milliseconds
99.98% <= 7 milliseconds
100.00% <= 8 milliseconds
74074.07 requests per second

====== PING ======
10000 requests completed in 0.12 seconds
50 parallel clients
3 bytes payload
keep alive: 1

43.79% <= 0 milliseconds
99.80% <= 1 milliseconds
99.85% <= 2 milliseconds
99.89% <= 3 milliseconds
99.91% <= 4 milliseconds
99.93% <= 5 milliseconds
99.97% <= 6 milliseconds
100.00% <= 7 milliseconds
86206.90 requests per second

Yeah, you read that right. On this somewhat low-end computer (by today's standards), Redis still manages to do over 74,000 SET (write) and GET (read) operations per second. Push and pop list operations also do well over 70,000 requests. On bigger hardware, expect these numbers to be much higher. Besides speed, I've also been impressed by the stability of Redis. I've been running Redis non-stop on the Mac Mini for over two weeks, and I've never had a single issue with it.

I got really interested in Redis after Defunkt (of GitHub fame) open-sourced Hurl. Hurl was an entry in this year's Rails Rumble competition. I used it quite extensively when developing with PayPal's APIs. After it was released, I noticed that Hurl used Redis for persistence. I was kind of puzzled why a key-store value was used for this. However, Defunkt wrote an excellent post mostly explaining the SORT operation, but also included some additional details on how Redis was used in Hurl. It made the decision to use Redis clear. Well, I'm also willing to bet that he used Redis because us programmers love to use the new hotness.

I feel that Redis will be something big soon. There are a few open-source projects using it, including the aforementioned Hurl and Resque. I already have a few ideas where I can use some of this functionality for current sites that I'm working on (such as simple counters, or a tag-like system where we can push and pop tags from a list). Check Redis out if you need some quick and simple storage.

Testing Windows 7 on a MacBook Pro

Posted on June 13th, 2009 in Guide, Reviews, Software, Windows | Comments

I had some time to spare during the weekend, so I decided to have some fun with my MacBook Pro. Now, I’ve been more or less full-time Mac user for the past year (I use Ubuntu Linux from time to time, though) ever since I could afford getting a Mac. Yes, Macs are expensive, but totally worth every dollar, in my humble opinion. But I digress.

In any case, I also stopped using Windows because of all the issues surrounding Vista. While there have been people who say that there’s nothing wrong with the operating system, in the time I’ve used it I found it extremely slow on a computer with more-than-decent hardware and experienced constant lock-ups and crashes. It might work fine for some people, but it never was the case for me.

Lately, I’ve been hearing more and more about Microsoft’s next operating system release, dubbed Windows 7. In a totally welcome change of pace for the company, Microsoft has allowed any user, not just developers or OEMs, to be able to download and test beta versions of the operating system. Everywhere I go on the Internet, people have only great things to say about it – essentially that it’s faster and more stable, even in its pre-release state.

As always, the curiosity is killing me, so I decided to take the latest release for a spin. I have plenty of free space on my MacBook Pro, so I decided to use Apple Bootcamp to test this out. Here’s an outline of the steps I took to successfully install Windows 7:

1) You can start off my downloading WIndows 7. At the time of this writing, Microsoft is offering users to test out the first Release Candidate for Windows 7 (stated for official release on October, 2009). When downloading, you have the opportunity to choose to download Windows for 32-bit architectures or 64-bit architectures. Since this post is for installing Windows 7 on a MacBook Pro, I chose to download the 64-bit version, although the 32-bit version should work just fine. Keep in mind that you’ll need a high-speed connection and a DVD burner, since the DVD image is approximately 3.05 GB.

By the way, when you download the DVD image, there will be a product key for Windows 7. Write this down, because you’ll be asked to enter it to activate Windows during the final steps of the installation process. Don’t worry if you forget – You’ll still be able to install Windows properly and activate it at a later date. But it’s just easier to do it from the beginning. Also, make sure you have your Mac OS X Installation Disc on hand. When Windows is installed, you’ll need to install the proper drivers for your hardware, and the Mac installation disc has them readily available.

2) Once you get the image downloaded and burned onto a blank DVD, you’ll need to partition your hard drive and create some space for Windows. I explained this in an earlier post, but I’ll just post it here since it’s slightly different. If you have Mac OS X 10.5 (Leopard) installed, you can use the Boot Camp Assistant to create a partition. Unfortunately, at this time, you won’t be able to use Boot Camp if your Mac is running Mac OS X 10.4 or an older version.

When starting the Boot Camp Assistant, you will be asked to specify the size for your new partition. For the 64-bit version of Windows 7, the minimum requirements are to have at least 20 GB of free hard drive space. I recomment using at least 30 GB of free hard drive space, since you’ll most likely want to install and test out some Windows software. Once the partitioning is completed, the Boot Camp Assistant will ask if you would like to restart to begin installing your new operating system. Before clicking on the ‘Start Installation’ button, insert your newly-burned DVD of Windows 7. Once the DVD has been detected on your Mac (the DVD icon of the mounted drive should appear on your desktop), click on the ‘Start Installation’ button. The Mac will restart, and will boot from the DVD and start the installation process.

3) Installation is a fairly easy process. Over the years, Windows has streamlined the installation process of their operating systems, and it seems Windows 7 is the easiest one yet. The only small issue you need to look out for is that while the hard drive was partitioned properly, it wasn’t formatted for Windows 7 (specifically, NTFS). It’s fairly easy to correct this, though.

When you get to the section where all your computer’s drives are displayed, you’ll notice one labeled ‘BOOTCAMP’. This is the one the Boot Camp Assistant conveniently created for you. When you click on this drive, you’ll notice a message saying that Windows can’t be installed on that drive, before of the aforementioned issue. To correct this, click on ‘Drive Options’ after selecting the partition. There will be multiple options for you. Simply click on ‘Format’ to format the disk properly. Once this step is done, you can click ‘Next’ to install the operating system to the partition.

4) Please note that during the Windows installation process, your computer will be rebooted a few times. When your computer reboots, it won’t boot back to Windows automatically. Instead, it will boot back into Mac OS X. To be able to choose which partition you want to boot from, you need to press and hold the Option key before the Apple boot screen appears. This will them display all bootable partitions on your Mac. You should have one for your Mac OS X installation, and another for WIndows. Choose the Windows partition and hit the ‘Return’ key to boot back into Windows. Remember to keep an eye out while Windows is installing, or else you’ll find yourself rebooting from Mac OS X constantly.

5) Once Windows is installed, you’ll notice that the resolution is pretty crappy. This is because you have to install the drivers for the video card and other hardware in your Mac. This is where the Mac OS X installation disc comes in handy. Eject the Windows 7 DVD from your drive. In my MacBook Pro, I couldn’t get the DVD to eject by pressing on the Eject button on the keyboard. I was able to eject the disc by going to ‘Computer’ from the Windows menu, clicking once on the DVD, and then selecting ‘Eject’ from the toolbar.

Insert the Mac OS X installation disc into your computer. You should get a message asking to auto-run the setup program from the disc. Do not run this, as it will install the 32-bit drivers. Instead, go to the Windows menu, select ‘Run’, and enter D:\Boot Camp\Apple in the field and click ‘OK’. There should be an executable file called Bootcamp64.msi in the directory. Double-click this file, and the drivers installation process should start automatically. After they’re installed and your computer reboots, you’ll have a fully-functional Windows 7 installation on your MacBook Pro!

This might seem to be a long process, but I think I’m just being too verbose in writing. It really is a short, straight-forward process. As I mentioned above, the installation process is fairly easy. Although I’m guessing that most Windows users won’t go through this process, as they’ll most likely already have it installed on any new computers they purchase. But for those who actually have some fun doing the whole installation thing, it really couldn’t get easier than the Windows 7 installation.

As far as the actual operating system goes, it does seem faster and much more stable than its predecessor. In the couple of hours I spent today using the operating system (and typing this blog post, as well), I didn’t encounter a single problem. I also installed quite a lot of software, and they all ran without a hitch. So far, so good.

I don’t have any official numbers here, but I’m willing to bet that while Microsoft still has the dominant share of the operating system market, it has lost more than a few percentage points. Although that didn’t happen solely because of Vista, I know more than a fair share of people who have dumped Vista for alternatives, with many more downgrading to Windows XP. Windows 7 feels like it’s a step in the right direction for Microsoft. I just wonder if Apple will be able to continue to run those snarky ads for long.

Installing Ubuntu 9.04 on a Mac Mini

Posted on May 25th, 2009 in Linux, Mac, Open Source, Software | Comments

Ever since I bought my MacBook Pro a few months ago, my poor ol’ Mac Mini has been alone and lonely. I really didn’t have much use for it, since I transferred all important work files to my new laptop. So what would I do with it? That’s when Ubuntu 9.04 was released. Back when I was in Puerto Rico, I would always get excited when a new release of my favorite Linux distributions (Fedora, Debian, Slackware and Ubuntu) was announced. It had been a while since I gave one of these new releases a test drive. It would also give me a chance to use my Mac Mini as a server, where I can test some new software that I’ve been wanting to check out for a while.

The Mac Mini seems like a good, cheap alternative for a server if you have one lying around unused. These machines are pretty quiet, consume low amounts of energy and are fast enough for most server tasks. Here were the steps I took to get a fully-functional Ubuntu Server installation on my Mac Mini. As a side-note, my Mac Mini is a Mac Mini Core 2 (1.83 GHz) with 1 GB of RAM and an 80 GB hard drive.

1) Download the Ubuntu Server disc image and burn it to a CD. I chose downloading via BitTorrent. Also, I downloaded the 64-bit version (torrent filename: ubuntu-9.04-server-amd64.iso.torrent), although the 32-bit version should work just fine. Make sure you seed for a while after you download your disc image!

2) You will need to partition your Mac Mini hard drive, to create some space for the Ubuntu installation. If your Mac Mini has Mac OS X 10.5 (Leopard), you can use the Boot Camp Assistant to create a partition. Unfortunately, you won’t be able to use Boot Camp if your Mac Mini is running Mac OS X 10.4 or an older version. When starting the Boot Camp Assistant, you will be asked to specify the size for your new partition. You’ll need at least 10 GB of free space in your hard drive to do this. Depending on how much hard drive space you have available, create a partition. Once completed, the Boot Camp Assistant will ask if you would like to restart to begin installing your new operating system. Don’t do this just yet. Quit the Boot Camp Assistant.

Note: I was having problems creating a partition, even though I had plenty of free space on my hard drive. The reason was because my hard drive was apparently too fragmented, and there were some files that couldn’t be moved to create the new partition. Since I have a 500 GB external drive and use Time Machine to back everything up, I decided it would be best to just do a clean install of Mac OS X 10.5. Once Leopard was installed, I created the new partition using Boot Camp Assistant without any problems.

3) Before restarting your Mac Mini, you will need to install a boot manager called rEFIt. rEFIt will help install Ubuntu easily, and makes selecting between Mac OS X and Linux after installation a breeze. To install rEFIt, download the Mac disk image (.dmg) file. Once the image is mounted, install the boot manager by executing the rEFIt.mpkg file. After installation, to make sure the boot manager was properly installed, there should be a directory named /efi in the root directory of your system. Open the Terminal application on your Mac Mini, and execute the following commands to properly install the boot manager (You will be prompted for your password):


cd /efi/refit
./enable-always.sh

4) After rEFIt is installed, insert the Ubuntu Server CD you created and restart your Mac Mini. When rebooting, you’ll immediately notice the rEFIt boot manager screen. This boot manager should recognize the Ubuntu Server CD (marking it with the ubiquitous Linux penguin logo). Select this option, and the Ubuntu installation process should begin.

5) Installing Ubuntu is beyond the scope of this post, but it’s pretty easy to install if you have never done it before. Don’t be intimidated by the command-line look of the installation process! Just following the instructions and everything should be installed in no time. There were a few things I had to do differently in my case:

  • When the Ubuntu partitioner starts, it will show all available partitions in the hard drive, including the partition for Mac OS X. You’ll recognize the difference between the Mac OS X partition and the one you created using the Boot Camp Assistant by looking at the format of the partition (Mac OS X uses the HFS format, while the one you created is using the FAT32 format). Since I wanted to use a different format for this partition (ext3), I selected the FAT32 partition and deleted it. Once deleted, you’ll see ‘Free Space’ where your partition used to be. Select the free space, and the partitioner should ask if you want to let it create the necessary partitions. This is the easiest way to set up your new partition for Ubuntu.
  • After installing the operating system, the Ubuntu installer will ask where you want to install its boot manager, GRUB. Since we don’t want to over-write rEFIt that’s install on the drive’s Master Boot Record, we need to install the GRUB boot manager in the boot record of the new partition. So where the installer prompts you to write the location where GRUB should be installed, write hd(0,2), which is the location of the new partition (provided you only have the Mac OS X partition and the new Linux partition).

6) If everything went smoothly, your Mac Mini will eject the CD and reboot. rEFIt will be on display once again, this time letting you choose to boot Mac OS X or Linux. Select Linux, and after all of Ubuntu’s processes start, you’ll be presented with a prompt. Congratulations, you have Ubuntu 9.04 installed in your Mac Mini!

I’m sure that installing any other Linux distribution will be more or less the same. Keep in mind that since I installed the server edition of Ubuntu (command-line only), I have no idea if video, sound, wireless connectivity (I connected my Mac Mini to my router using a Cat-6 cable) or other things will work properly in a Mac Mini. I’m sure the Ubuntu community (and the Linux community in general) have solved most common issues by now. If I install a different Linux distribution using a GUI, I’ll write about it and let everybody know.

Dropbox – Never leave your files behind again

Posted on September 12th, 2008 in Mac, Services, Software | Comments

I’m pretty damn excited by the long-awaited public launch of Dropbox, an online file storage service. Well, it’s more than that. It’s a service that allows you to store, share and synchronize your files, either on the web, or as a ‘dropbox’ folder on your computer. They offer a nice chunk of space – 2 Gigabytes, which to me is more than enough for the things I would usually store in these services.

It might sound like just another online file storage site, but it really is not. It’s ridiculously easy to use. Once you install their client software and create an account with them, your computer will have a special folder, where you can just drop files in and they will automatically be synced on your account. No need to do any manual syncing or waiting for a timed sync to occur. It’ll happen totally transparent from your regular workflow. Provided you have a fast Internet connection, the synchronization process is virtually instantaneous. Then you can either grab the files from a web interface, or by installing and configuring the client in another computer. It’s that damn easy. Take a look at the tour they have on their site.

I must admit, I was a bit skeptical about this service after I read about it in TechCrunch earlier this year. I thought it wouldn’t be anything special compared to any other site that provides similar services. However, after reading more and more about it, the curiosity got the best of me. I scrounged for an invite and eventually got one. I signed up, but to be honest I never used it much. I only have access to Mac and Linux computers at the moment, and Dropbox was Windows and Mac only, so I was rather limited as to where I could use it.

However, the excitement arrived yesterday, when not only I read that Dropbox launched publicly, but they also released a Linux version of their client software! I immediately downloaded the client at work (laptop using Ubuntu 8.04), created my account. and it worked just as it did on the Mac. I started transferring files and got them when I arrived home. Everything went without a hitch. I’m now finding more and more uses for Dropbox, particularly work-related files that I can access at home.

Kudos to the entire Dropbox team for putting out some quality work.

Fluid and Prism – Site Specific Browsers Are Awesome

Posted on September 11th, 2008 in Linux, Mac, Software | Comments

At my recommendation, my company started using Campfire by the awesome guys at 37signals. In case you don’t know what Campfire is yet, it’s a site where groups of people can chat, upload files, share code and many other collaborative activities. I recommended Campfire because I think this is just what our company needed during this time where we have testers who are in other cities. It’s my first time using Campfire in a business environment, and hopefully it all works out well.

One of the things that initially worried me about Campfire is that being a web-based app, it would be difficult to know when there was any activity on the site. The good thing is that Campfire has an audio alert, a pleasant beep, that alerts me whenever someone wrote something in the chat rooms I’m at, along with changing the title of the page so that I can spot it in my open tabs. However, I’m guessing that I’m not the only web developer who has a myriad of tabs open at any given moment. Site testing, analytics, API specs, build/test results Google – All of them usually occupy a space in my browser. Adding Campfire would mean that it would get lost in a sea of tabulated titles.

After seeing this could be a problem, I immediately thought of Fluid, which I had used previously. Fluid is a browser of sorts. However, instead of being just another browser, Fluid allows you to create an app that’s site-specific, so your web-based apps will act like an independent desktop application, separate from whatever you have in your browser. It’s perfect for those sites which you constantly have open, such as web-based E-Mail like Gmail, social networking sites like Facebook, and, as in my new-found case, chats like Campfire. It will also alert you whenever there’s a change in the site you’re visiting, right on the application icon in the dock. So, as an example, if you’re using Gmail, you’ll see new mail notifications in the dock, instead of needing to open the app window. It’s pretty neat and convenient.

I was happy that I found a solution. One ceveat, though: Fluid is a Mac-only app, and I use Linux at work (at least until the bosses buy souped-up Macbook Pros for their developers… I can dream, can’t I?). So I was bummed out again. Then I remembered that Mozilla was developing an app with a similar concept, called Prism. The functionality is virtually the same: You set up a site to be run as a desktop app, making it totally independent from your regular browser.

Seeing that Prism is in the Mozilla Labs, I didn’t expect much of it. However, it works great on my Linux laptop under Ubuntu 8.04. I was able to create a Campfire app and add it to the desktop with ease. It never crashed on me or gave me any problems during the entire afternoon I was using it. Granted, there wasn’t much activity going on in the chat rooms at the time, but everything worked as if I were working on Firefox.

The main difference between Prism and Fluid is the fact that Mozilla is making Prism available not only for Mac, but for Windows and Linux as well. Of course, Fluid is written with Mac in mind, and it has all sort of goodies for the Mac (like the aforementioned updates in the icon, Growl notifications, its own JavaScript API and more), so you’re much better off with Fluid if you’re on the Mac. For the rest, then Prism seems like a mighty fine solution in the meantime.

With more and more web-based apps taking up the majority of our time in front of a computer, I think these applications will be more widely used in the near future. You can already see some sites adopting it, even including icons for your usage of the desktop, like GitHub and 37signals. There’s even a Flickr group adding more and more site icons every day. If you haven’t checked out either of these apps, you should check them out now.

Delete Your Crap

Posted on May 6th, 2008 in Open Source, Opinion, Privacy, Software | Comments

I posted this story on a non-technical message board I frequently visit, as a service for some of the users there who might not have a clue on how easy it is to retrieve data from a supposedly-formatted drive. I decided to pass it along here as well. I think privacy is very important, and with the proliferation of electronic devices that store data, it’s getting easier to retrieve information from others.

Here’s a story of some dumb-ass kids who recorded themselves smoking weed on a digital camcorder, returned the camcorder to the store, forgot to erase their tapings (most likely due to said kids smoking weed previously) and the next person who bought the open-box camera from the story posted the videos all over the Internet for all the world to see:

Remember to delete your stuff from electronic equipment if you’re returning it, selling it or giving it away. And even then, be wary of it.

I was once sold a USB flash drive from a friend, and although my buddy deleted the contents, I was able to see what he had their previously before with a freely-available program off the Internet (don’t remember exactly which one right now), out of curiosity. Dude had some… let’s say ‘interesting’ pics of his then-girlfriend.

His way of deleting the contents was to simply do a quick format on the drive from his Windows machine before giving it to me. To avoid all the technical details, for those who don’t know, what this does is simply destroy the FAT table and/or boot sector, which is a sort of ‘table of contents’ for the drive, thus nothing appears when you try to access the drive. But the data is still in the drive’s sectors, and unless you rewrite those sectors (either by copying something new in the flash drive or using some software, which I’ll get to in a minute), they’re easily accessible.

The program I’ve used for a while with Windows is called Eraser (I carry a portable version of this program on my USB drive, called Eraser Portable), which makes sure your data is clear from your portable device (like flash drives, SD cards for digital cameras, even iPods). In short, what this does is over-write the sectors on the drive multiple times with ‘garbage’, so it’ll be virtually impossible to get that information from freely-available tools. I’m guessing the government has more advanced tools, so for the overtly paranoid, you’d be better off just smashing the drive to pieces and dipping them in a vat of acid.

Just wanted to pass this info along so you people can keep your privacy, and know how easy it is to grab a hold of your data.

Respect RSpec

Posted on January 4th, 2008 in Ruby On Rails, Software, Web Development | Comments

Over the past week and a half, I’ve been busting my ass trying to learn the ropes of Behavior-Driven Development with RSpec. I had been interested in learning either Test-Driven Development or Behavior-Driven Development for quite a while, so I just jumped on one of the two and test the waters out for a while.

I’ve been reading a lot on TDD and BDD for the past couple of months, yet never took the time to implement it to my current projects. The main reason is because I thought it would take me too much time to learn and would bog me down too much, when all I wanted was a workable application running as soon as possible. But, an opportunity presented itself (more on that in the future), so I chose the development technique that seemed better for me: BDD.

Reading about RSpec through other blogs on the Internet, it just seemed so intuitive to use that for testing, I kinda thought it was too good to be true. So after installing RSpec and getting it running on my application, I realized it was true after all. It’s ridiculously easy to write your own tests with RSpec, and it’s almost plain English (just like good ol’ Ruby). It includes built-in stubs and mocks to simulate parts of code, so you can even drop fixtures if you want (although admittedly, a lot of the shortcomings fixtures had were fixed with Rails 2.0). In fact, here’s a simple controller test:

describe ProductsController do

  before(:each) do
    @product = mock_model(Product, :to_param => "1")
    Product.stub!(:find).and_return(@product)
  end

  it "should call the action successfully" do
    get :show, :id => "1"
    response.should be_success
  end

  it "should find the product" do
    Product.should_receive(:find).with("1").and_return(@product)
    get :show, :id => "1"
  end

  it "should assign the found product for the view" do
    get :show, :id => "1"
    assigns[:product].should eql(@product)
  end

end

This test actually works for testing the show action in a controller. I wrote this just to show how readable the code is. I never knew testing would be so readable! And like I said, once you wrap your head around mocks and stubs, it’s ridiculously easy to implement. As a great bonus, RSpec can also integrate with rcov, a tool that actually checks what parts of your code are tested. It’s a great tool for making sure you achieve 100% coverage of your code.

Unfortunately, I didn’t actually do any BDD this time around, as I already had a good chunk of my application up and running already. But now that I have discovered the joys of RSpec, all my upcoming products will be fully done using BDD techniques: I won’t write a line of code until I write the behavioural test before.

A couple of ceveats, though. Hey, nothing’s perfect! First off, if you use different types of plugins for your application, you’ll find some parts of it difficult to test in RSpec. Most plugins use the Ruby’s own Test::Unit testing framework to test their own functionality, but parts in your code where you use these plugins can get you the first time around. Also, if you’re like me, and already have written code for your app, you’ll start finding different ways to fix your code to conform to RSpec testing. This isn’t necessarily a bad thing, as this is most likely a warning sign that you need to refactor that piece of your code anyway. But it’s takes a bit of your time away, so be prepared for this.

In short, RSpec is so easy to use, I don’t see why people shouldn’t use it in their own projects. I suggest every Rails developer should look into RSpec (or any other testing method, really) and stop being lazy. I know I was, but never more!

RSpec References

Ryan Bates from Railscasts has a great screencast that can serve as an intro to testing controllers. And the best part is that it’s free!

* Testing Controllershttp://railscasts.com/episodes/71

Geoffrey Grosenbach over at PeepCode has an excellent three-part series on RSpec, with about three hours of RSpec goodness! No, they’re not free, but the $9.00 per episode is truly worth it. This was my secret weapon in learning RSpec in less than two weeks – The best 27 bucks I’ve spent in my software development career!

* RSpec Basicshttp://peepcode.com/products/rspec-basics
* RSpec Mocks and Modelshttp://peepcode.com/products/rspec-mocks-and-models
* RSpec Controllers and Toolshttp://peepcode.com/products/rspec-controllers-and-tools

Source Code Management – Not just for teams

Posted on November 12th, 2007 in Open Source, Programming, Software | Comments

I’ve been meaning to write about the subject of Source Code Management for a while now. The reason for this is that I’m very surprised about the amount of software developers I personally know who don’t use any type of Source Code Management tool at all. The main reason of this is because these people don’t even know such a tool exists. The very few who do know about these tools just know how it works, but never use it themselves. It’s shocking, to say the least.

When I got this VPS, I immediately installed Subversion for my own personal projects, even though I’m the only one working on said projects. This is where those very few people I mentioned above think wrongly about these tools. Their basic response was “If you’re the only one working on the code, why do need to share it?” Very big misconception, to say the least.

The reason I originally started learning about Source Code Management tools (first started with CVS, then move to Subversion, where I have stayed ever since) because there was an additional programmer in my company who was beginning to modify the software where only I had previously worked on before. So yes, I used SCM tools to ’share’ code and make sure our changed didn’t conflict with each other. But then I realized that I was only using probably less than 5% of its true power.

When I did a major screw-up and pushed some bad code into the repository and then into production by mistake (it was actually incomplete code I had mistakenly committed to the repository), I was grateful that I could roll back almost immediately. Then when I needed to have a separate copy of the code, I learned the wonders of branches and tags.

After these experiences, I wondered how I ever did any serious programming work without any Source Code Management. Right now, whenever I start a new project, I immediately create the basic folder structure for the SCM before doing anything else. I think it’s crazy to go forward with a new project without any SCM in place, which makes the fact that a lot of programmers aren’t using any SCM just insane.

For those of you not using any SCM right now, shame on you! Allow me to redirect you to a couple of interesting articles for my preferred SCM tool of choice, Subversion. Please note, there are a lot of different SCM options out there, both commercial and open-source. I would recommend doing some research first on these different tools before deciding to go with one.

Subversion Book – Version Control With Subversion – Excellent resource not only for finding out how Subversion works, but how SCM tools work in general.
Software Branching And Parallel Universes – Great blog post from Coding Horror that explains how branching works visually, along with some reasons when not to use branching.

http://www.codinghorror.com/blog/archives/000968.html

I want everything!

Posted on October 12th, 2007 in Open Source, Programming, Ruby, Ruby On Rails, Software, Web Development | Comments

The past two weeks I’ve been totally separated from all of my learning and reading processes I’ve established to myself, and I felt terrible for doing that. It’s not like I’ve been totally disconnected from everything. I’ve still read all my favorite programming-related blogs, as usual. Still, I haven’t just sat down to absorb everything or practice.

These past two days I decided to get back on track. However, I found myself with the same problem I’ve had for a while now. Whenever I sit down to learn something, I want to learn everything. I don’t mean “learn everything of something“. It’s more like “learn something from everything“.

For the past months, I’ve had a hundred different interests. I’m interested in learning Adobe AIR. Microsoft Silverlight sounds like something I could use in the future. I was sold on Test-Driven Development and ever started to adopt its practices to my daily usage, yet recently I’m liking the sound of Behavior-Driven Development more and more and would like to test that road. I want to learn other web frameworks in different programming languages, like Django and CakePHP. And of course, I’m still totally into Ruby and Rails.

I know a lot of people who don’t mind knowing about everything. But the deal is that by learning (or having the desire to learn) about so many things, you don’t fully learn it all. You only learn a bit about each thing, but never a whole lot. There simply isn’t enough time in the world to do so, especially with a full-time schedule. So to say it’s frustrating is an understatement to me.

One technique I’m finding useful to juggle these interests is to create a necessary project in your mind to learn along the way. This should keep your interests level high during the learning process, while making you stay focused with one or two things at a time. For example, my next project is a web application, where I’ll strictly try to use the practices of Behavior-Driven Development while learning to use RSpec. This way, I’ll be learning a lot of different, yet related, subjects at the same time. After this project is done, I’ll see where Adobe AIR has headed, since it’s still in Beta. If it still piques my interest, I’ll create a new project for one of my current needs, and learn from there.

Being in this world of programming and technology, where it seems like time is always on fast-forward, it can be tough to keep up with what you like. But at the same time, it’s just fun. Even though I get frustrated at times, I’m having a ball learning these things. I guess it all boils down to that for now.

Capistrano – Like that person you hate, yet end up falling in love with

Posted on September 3rd, 2007 in Open Source, Ruby On Rails, Software | Comments

One of the reasons I went exploring into Rails was because of Capistrano, a utility that greatly helps deploying Rails sites into production servers, by automating many of the tedious setup steps needed to deploy new changes into production. I know I can’t be the only one who has once or twice pushed some new change into production, only to discover (by myself or an angry user) that I forgot to bring the database schema up-to-date as well. Capistrano (actually, migrations are the key component here) will never allow that to happen again.

In a nutshell, Capistrano does the following:

  • Logs into your server via SSH
  • It creates a directory structure that’s useful in case you want to rollback some bad code you mistakenly pushed unto the server
  • Uses Subversion (or other SCM) to checkout the latest code committed into the repository and downloads it
  • Automatically runs all migrations to make sure the database is up-to-date
  • Runs other scripts, like making sure your FastCGI processes are restarted and running correctly, or restarting your web server

After nearly finishing my first public Rails site (coming soon, I promise!), I wanted to learn how to use this tool by deploying the first version into my VPN space using Capistrano. I thought this would be a daunting task, and at the beginning it was thanks to some minor errors, but after that, it was total bliss. After a few hours of tweaking my settings, I finally got it to work, and all deployments from here on out should be as simple as writing cap deploy without and remorse.

I’m going to write how I set up my deployment environment, so if anyone has had similar problems to mine, they can hopefully get past them.

First off, let me write about my app and server environment:

  • Operating System: CentOS 4.5
  • Webserver: Lighttpd 1.4.15
  • Rails Version: 1.2.3
  • Mongrel: 1.0.1
  • Capistrano: 2.0.0

After installing Capistrano on my development computer (simply using gem install capistrano --include-dependencies), I was ready to “capify” my application. To create the files used for deployment, just issue capify . at the root directory of the Rails application. This creates two files: Capify, which points to the second file, config/deploy.rb, which is the actual deployment configuration file.

The configuration is pretty straight-forward. There are some default settings that can e easily changed to reflect your production server setup. I did just that, and that’s where the ‘gotchas’ started pouring in.

After I changed the default values to my own, I wanted to set up the directory structure in my production server. To do that, simply run cap deploy:setup in the root directory of your application. That should prompt you for your SSH password to create all the directories needed in the directory specified in the deployment file (using the :deploy_to variable). However, when I did that, I got a nice error message: no such file to load — openssl.

After searching a few minutes in Google, I found my problem: I had compiled Ruby from source without the openssl-devel libraries installed in my system. Without the header files, Ruby compiled without OpenSSL support. So after installing the OpenSSL header files and recompiling Ruby (don’t forget to run make clean before recompiling), I was faced with another error message: It stated that my server didn’t exist. Then I remembered I’m running SSH in a non-standard port. Capistrano assumes it’s running on the default port, which is 22. After a few more minutes of searching, I found an option that needed to be added to the deployment file: ssh_options[:port] = xx, where xx is your SSH port number. After these changes, I was golden, as Capistrano asked for my SSH password.

After entering it in and seeing some progress in the directory creation process, I was faced with yet another error message, about a user not existing. I was assuming Capistrano was using the user name from my development box to log into the production server. In any case, this was fixed by adding another option in the deployment file: set :user, "production_user", where production_user is the user name with the appropriate permissions to create the directories and files in the production server. I ran cap deploy:setup once more, and all my directories were created. Success! Little did I know that would be only the first steps, and more troubles were looming ahead.

Once I verified the directory structure was created correctly on my production server, I went ahead and ran cap deploy:cold, which deploys my latest working version to the server, runs all migrations, updates all symlinks to the current code, and runs all remaining processes, like respawning all FastCGI processes, for the very first time. I once again ran into a small snag, as I was having permission problems running some scripts on the production server. After some more minutes of searching, I found that there’s a variable that needs to be set to make sure Capistrano runs the scripts as a specific user with adequate permissions. After adding set :runner, "production_user" (once again, where production_user is the user with the correct permissions to run your application scripts) to my deployment file, I was able to pass the permission parts, but then I hit yet another snag: I was missing a file – script/spin.

I found it odd that Capistrano was looking for this file, as it’s not automatically generated either by Rails or Capistrano. But after calmly reading the Capistrano installation instructions (instead of skimming over most of it), I saw that this file is used to recreate (or create) the FastCGI processes in your production server, to ensure that the users will get served the latest version of your app. There are many different ways to set up your FastCGI processes, depending on what the web server you’ll use. Since I use Lighttpd, I’ll be writing about that here. But you can find tons of useful information on the Internet if you use Apache, nginx or any other web server.

To remedy this problem, all I needed to do was to create the script/spin file (with executable permissions – chmod 0755 script/spin) with the following line (where /root_of_app/ is the path you described in the set :deploy_to: variable in the deployment file):

/root_of_app/current/script/process/spawner -a 127.0.0.1 -i 3 -r 5

This script calls another script called spawner (included in current versions of Rails), which verifies if there are FastCGI processes currently running. If the processes exist, they’re recreated to show the new version of the app. If the processes don’t exist, they’re created. The -a switch indicates the IP address used to direct the FastCGI processes. If you don’t use this switch, it will default to 0.0.0.0, which was causing me problems later on. The -i switch tells the script to create three FastCGI processes in sequential ports. Finally, the -r switch tells the script to verify if these scripts are still active every five seconds. This makes sure that all processes are running smoothly. One switch I didn’t use was the -p switch. By default, the spawner script creates all FastCGI processes starting with port 8000. Using the -p switch, you can specify which is the first port. In my case, the three FastCGI processes are creates using ports 8000, 8001 and 8002. You can change that default if you wish.

After you create the spin script, you’ll need to commit it to your SCM so Capistrano can find it in the production server. Once committed, I re-ran the cap deploy:cold command, and I was greeted with success at the end. My latest version of the application code was sent to the server, all migrations ran, and the spin script created three FastCGI processes on my server. Awesome! My work here with Capistrano was done. After hating Capistrano for a good while, I fixed all the kinks and can now never live without it. I love you, Capistrano.

Feeling good for myself, I immediately fired up my browser and entered my site’s URL. Too bad only 500 – Internal Server Error appeared when I went to the site. Curious, I entered the URL once again, appending :8000 at the end of the URL, and lo-and-behold, the site appeared in all its glory. So the FastCGI processes created with Mongrel were working well. But my web server wasn’t transferring the requests to one of the three processes.

After looking around for more information, I saw how FastCGI processes, Mongrel and Lighttpd work together. In a nutshell, the request for the site is sent to Lighttpd, the web server. Lighty then needs to process this request and send it over to one of the FastCGI processes, which then displays the site on the user’s screen. Lighttpd is simply used in this case as a proxy, and lucky for me, it already has some basic proxy functionality built-in. However, it needs to send the the request somewhere. I saw some tutorials online that set this up, but it seemed to always send the request to only one of the three processes, which wasn’t efficient at all.

Here is where Pound comes into play. Pound is reverse-proxy and load balancer for web servers. Basically, it takes all requests from the web servers and passes it along to the processes running the site, making sure that all processes aren’t over-worked by load-balancing all requests. After installing Pound on my production server, I had to create a configuration file, by default stored in /usr/local/etc/pound.cfg (your location may vary, depending if you compiled and installed the program from source, or just installed a package):


ListenHTTP
Address 127.0.0.1
Port 7999
Service
HeadRequire "Host: .*site.com.*"
BackEnd
Address 127.0.0.1
Port 8000
End
BackEnd
Address 127.0.0.1
Port 8001
End
BackEnd
Address 127.0.0.1
Port 8002
End
End
End

This configuration will make Pound listen to the requests on port 7999 in the local machine (my production server), and forward the site’s requests to one of the three FastCGI processes created by the spawner script I talked about previously. I was surprised at how something so powerful could be easily implemented.

Now all I needed to do was to configure my web server to direct all site requests to Pound, which in turn passed them along to one of the three FastCGI processes. Skipping all the other default settings and changing all sensitive info that may compromise my site, here are my current Lighttpd settings for the site in question:


$HTTP["host"] =~ "(^|.)site.com$" {
server.document-root = "/home/production_user/railsapps/app_name/current/public"
server.error-handler-404 = "/dispatch.fcgi"
server.errorlog = "/var/log/lighttpd/site.error"
accesslog.filename = "/var/log/lighttpd/site.access"
proxy.server = ( "" => ( "site" => ( "host" => "127.0.0.1" , "port" => 7999, "check-local" => "disable" )))
)

Make sure you load the mod_proxy server module so you can use the proxy.server option mentioned above.

Once I restarted Lighttpd, I entered my site’s URL, crossed my fingers, and… success! I finally had a working site, load-balanced and all. What set out to be a learning process in Capistrano in turn made me use load balancing techniques in my site, which was something I planned on doing, but on another day, thinking it was super-complicated.

From here on out, every time I make a change I want to push to my site, all I need to do is run cap deploy on my development box, and that’s it. Everything will be updated with a simple command. It’s truly worth the time I spent getting it to work. Now I will never have an angry user again because I forgot to update the database schema.

In all, I spent a few hours fixing all the small kinks I encountered along the way. But as all good things go, you need to bust your ass to get things working like you want to. I don’t mind at all, as I learned a whole lot in one day. I hope someone finds some solutions in this writeup.

In case you’re curious, here’s my deployment file, with all the sensitive info changed for obvious reasons:


# Application Name - Anything you want to describe your application
set :application, "app_name"
# The URL of your source code repository, pointing to the latest version
set :repository, "http://svn_repo/trunk"
# Set the user name to connect to the server via SSH
set :user, "production_user"
# Set the user name of the user with permissions to run the application scripts
set :runner, "production_user"
# Set the path where you want your application to be stored
set :deploy_to, "/home/production_user/railsapps/#{application}"
# Option to change the SSH port
ssh_options[:port] = xx
# The URL or IP Address where your application will be stored - Multiple sites can be specified
role :app, "xx.xx.xx.xx"
# The URL or IP Address where your application will be served - Multiple sites can be specified
role :web, "xx.xx.xx.xx"
# The URL or IP Address where your database lives - Multiple sites can be specified
role :db, "xx.xx.xx.xx", :primary => true
# Task to restart the web server
task :restart_web_server, :roles => :web do
sudo "/etc/init.d/lighttpd restart"
end
# Restart the web server once the deployment is finished
after "deploy:start", :restart_web_server