New and improved but still the same
All the time, I see products that are boasting “new and improved” while also saying “same great formula”. What they do is just come up with a new look and feel and expect customers who didn’t like it before to come back?
Does that actually work? It seems to be, if all you have is a new look, and I didn’t like your “formula” before, why would I use it now.
Pizza Hut is a good example of true “new and improved”. Their new pizzas are far better than they were before.
It’s my birthday! Enjoy this coupon for 29% off Trunks!
I was originally only going to mention this on Twitter to keep it more “exclusive”, but then was thinking that my goal is to make it so people can use this and enjoy it, not to limit it.
Today is my birthday… yes, woohoo. 29 years old, one more year left until I exit my “twenties”.
To share in the celebration, I’d added coupon to support to Trunks! For today only, if you sign up for a paid plan with Trunks, enter the coupon code “29bday” and get 29% off the price! Be sure to click “Apply” to get it applied. Get it while you can.
To convert to a paid plan, simply visit your profile and it will have a recommended plan on the sidebar. Click over to purchase it, and the coupon box is on the right side bar there as well.
BETA USERS: Beta users at Trunks already get a 25% discount when they upgrade, and the birthday coupon can be stacked on top of the 25% beta discount! The 29% will not be based on the original purchase price, but the discounted one. Normally coupons cannot be stacked, but I wanted this one to be stackable without making deeper changes to the cart.
Remember, its “29bday” for 29% off. Coupon expires at 12:00am tomorrow morning, Pacific Daylight Time.
One week with a Droid, and a few hours with an iPad
A little over a week ago, I finally took the plunge and traded in my iPhone 3G for a Motorola Droid. The reasons can pretty much be summed up as:
AT&T is slowly killing the iPhone. Its like an open wound.
I switched both my wife and I over from our iPhones to Droids. The biggest reason is we were tired of AT&T, and our contracts were up. It really does suck when you get poor coverage in your own home. Ironically, AT&T had announced a “100 day plan” in December, but we’ve just seen an influx of dropped calls and poor quality since then. The niceties of the phone are rather overshadowed when you don’t get service. This pain was mainly felt by my wife, who uses the phone functions far more than me.
After spending a week with the Droid, I am very please though. The open-ness of the platform is welcoming. Don’t like the home screen? You can replace it. Don’t like the dialer app? Replace it. And it is all just seamless. Don’t like an app you bought? I heard you can even return an app within 24 hours. The email app’s combined inbox is nice as well, since I have 3 mail accounts and like to look at all in a glance. I also got the Android 2.1 before weekend and was very pleased with the updates.
A few observations:
- Android apps don’t have as “nice” an interface as iPhone apps. I don’t understand why. They seem more boxy.
- Somebody please fix the IMAP unread bug! My Exchange account and Gmail accounts over IMAP are fine, but with SmarterMail all messages are always unread. Was saddened to see 2.1 didn’t fix it. Did some network sniffing and narrowing down the cause.
- The screen is nice and crisp. Text just looks better on it than my iPhone.
- Turn by turn navigation… do I need my Garmin anymore? (maybe only where I don’t get cell coverage for maps)
- Love the Weather app in 2.1… love that I can see the temperature/rain chances over time. Want to know the weather at 11:34am? No prob.
- Love the notification bar
- Love the multitasking, but with the “task killer” apps, its a flashback to old Windows Mobile PDA days.
- I love how the Android browser re-wraps the text when you zoom into an area. Makes it so the font size is nice and text is wrapped to so it fits.
- The battery info is awesome. Shows you exactly what apps have been sucking up your battery.
- I don’t like the duality between “Email” and “Gmail”. I added my Gmail account as an IMAP account, since having “Email” app for Exchange/IMAP and the “Gmail” app for Gmail accounts feels to segregated for no reason. You lose out on the combined inbox then, and the Gmail app doesn’t look as nice as the Email app.
- Thought I had more negatives for the phone, but really don’t.
Now of course after I got my Droid, Apple announces an announcement about iPhone OS 4 for Thursday. I don’t think I will be missing the iPhone though. The truth is, unless they’re announcing the phone on Verizon, I won’t regret it. I won’t purchase another iPhone until it is on Verizon. No sense having a phone and having trouble placing calls.
But when thinking about if it was something I’d regret, it made me realize a few things about how I use my phone and ultimately prompted me to get an iPad. When I thought about what I used my phone for, it came down to web surfing, Twitter, and email. Nothing that requires a “phone” and nothing specific to the iPhone. On top of that, a phone overall isn’t the best platform for something like web surfing. Try reading code or technical blog posts in that form factor? It sucks. I’d often flag pages/posts for me to read later on my desktop or laptop. Additionally, I am not out or traveling very often. Most of my usage is around the house… laying in bed in the morning, eating breakfast, downstairs when watching TV, *ahem*bathroom*ahem*.
The iPad really is a nice trade off in mobility and experience. I don’t need something ultra mobile in my pocket, just something I can carry around the house. And I want a rich experience so I don’t need a full system by me to get what I need. When I do travel, the iPad will still be an excellent companion. Willing to bet watching movies in flight on it is better than the iPhone (bigger screen!). Can take books with me much more easily (with the iBooks/Kindle app, why get an ebook reader?). Its basically multi-purpose. I look forward to much more book reading.
So I sold my old iPhone 3G to my brother-in-law, had a special to sell a VPS for a year for $500, and bam, iPad and tax paid for. The old iPhone 2G my wife had is now being used by Nick to entertain him while going potty (trying to potty train).
For me, the iPad is an excellent fit between a laptop and a phone. Mobility while having an excellent experience. I also plan on getting another iPad for my wife to replace her aging laptop. For her, it is the perfect full system replacement as it does everything she needs a computer for.
Introducing Papercut Web Edition
I’ve talked about the Papercut tool I’ve written before. I initially wrote it to scratch an itch I had with previewing and testing emails during the development process.
Recently though while working on Trunks, I’ve been feeling the need for an email testing tool for staging environments. Since Trunks involves several moving components, I have a staging environment set up so I can do live testing on features. Often times that testing involves emails. Since I run the staging environment with a snapshot of the live database, I want the emails to be sent and viewed for testing, but don’t want them going out to live accounts. Would hate for a user to mistakenly receive an email from my staging environment!
In comes Papercut Web Edition.

Papercut Web Edition provides you with an SMTP account that you can connect to, authenticate with, and send emails two. It works just like the desktop Papercut where messages sent to it are only stored locally, not sent on to their destination. It then allows you to view the messages through the website.

With this, when you set up a staging environment, you simply point it to the SMTP server and off you go. In something like Telligent Community, just a matter of quickly checking the Email Settings, or with a Rails app, just need to edit your “staging” environment configuration.
The service is provided free of charge. It is simply ad supported, so while using it you will see an AdSense banner on the side. I’ve tried to make it unobtrusive while at the same time striving for the service to generate something in return. I may be changing it to use some different ads if it gets some sponsors, as I don’t expect AdSense to really draw in a whole lot.
Currently, it will delete messages after they are 2 hours old. It is intended for testing emails, not retaining them, so the idea is you trigger the email, view it online, and then are done with it… or simply proving a way for emails to be safely sent while you test other aspects of your app.
I have several more features that will be coming down the road. Right now, it is rather simplistic as I created it quickly to solve my problem. But it has some big things coming to help tackle some other emails testing annoyances I’ve felt. It’ll also have support for attachments, embedded images, forwarding messages onto a live account, and much much more.
So the most important piece? The URL!
dummysmtp.com
All good names with Papercut in them were taken… and as a site URL, “papercut” has more connotations with paper and pain than email. Dummysmtp is very descriptive of what it does… may the SEO gods look fairly upon it.
Sign up today and try it out! Go forth and test emails… safely!
Selenium Server in NAnt
When configuring our Selenium tests to run out build server, one issue I ran into is that there wasn’t a lot out there in terms of how to get this set up. A few people had posted about having done it, but not how they did it. Overall, it isn’t incredibly difficult, but there are a few things that I got hung up on.
The way we run it is we start the selenium server in the background, and then have NUnit tests that run the stories. We can’t start Selenium in the foreground because then we couldn’t move on to the NUnit tests, but we also needed to register it as a Windows service on demand. To do that, we used a utility called Non-Sucking Service Manager (NSSM). It is like srvany from the Windows Resource Kit, but it works on Windows Server 2008 (and there was no publicly available Windows Resource Kit for 2008 I could find).
Here is our setup/teardown NAnt targets:
<target name="start.selenium">
<property name="jdk.bin" value="${environment::get-variable('JDK_BIN')}" />
<exec basedir="${common.folder}" program="nssm.exe" commandline='install Selenium "${jdk.bin}\java.exe" "-jar ${source.folder}\libs\selenium-server.jar"' />
<exec program="net.exe" commandline="start Selenium" />
</target>
<target name="stop.selenium">
<exec program="net.exe" commandline="stop Selenium" failonerror="false" />
<exec basedir="${common.folder}" program="nssm.exe" commandline="remove Selenium confirm" failonerror="false" />
</target>
On top of that, it is important to set the “nant.onfailure” property to a target that does all of your cleanup. Since we’re using NUnit, an error in the unit tests will signal a build failure, but we still want to ensure our cleanup runs. So set the “nant.onfailure” property to the name of a target that runs all cleanup tasks (including “stop.selenium”).
Proper cleanup is very important, since in our case, the selenium.jar is in with the source and if it is still running, Team City will be unable to cleanup the working space and cause it to instantly fail any future builds before it even gets to executing your script. Because of this, it might also be good to have the server do a scheduled task that calls “net stop Selenium”. If it is stopped already, no harm, if the service doesn’t exist, no harm, but just a bit of an extra measure. And finally, to be extra extra safe, I actually call our main cleanup target at the beginning of the build as well and set failonerror=”false”. Since we’re registering and running background processes, didn’t want the test to be brittle and need my intervention. I don’t want “Ken, can you fix the build” emails.
So few things to point out about using it:
- One thing I got hung up on, you need the quotes around the “-jar …” parameter on the exec line to nssm.exe. I was missing that originally and wasted a lot of time, since I’d see the Java process start and be running in the process list, but couldn’t communicate with the Selenium server. The “-jar …” line is a the parameter to java.exe though, and not nssm.exe, so it needs to know it is all one parameter.
- We have the location of the JDK set in the environment variables. I don’t like hardcoded paths in the scripts.
- Be careful of quotes! I had to have the JDK_BIN set to a property because otherwise I’d get down to invalid quotes. You can’t have commandline=’….”-jar ${environment::get-variable(‘JDK_BIN’)}”‘…. the second set of single-quotes will be closing the first one, not opening a new set.
- The “common.folder” and “source.folder” are just properties pointing to where some common utilities are and the current working directory for the source.
Team City & its levels of awesome
Recently, I’ve been working on migrating our build process at Telligent from using Cruise Control .NET to use JetBrain’s Team City. Cruise Control has served us well, but after looking at the feature set of Team City, it had a number of things that we were wanting to leverage as we continued to expand our build process. Was asked on Twitter what I liked so much about Team City versus Cruise Control, but there wasn’t a good way to sum it up in 140 characters. So here is a brief list of some of the reasons:
- No XML configuration files. Granted, our builds are in NAnt, so we’re still married to XML, but creating a new build doesn’t need to take any XML editing anymore. Our build scripts have no hard coded values, everything it needs it passed in from Team City. So we can go an existing build, click Copy, then just edit the configuration settings as needed.
- It queues builds. We run a number of daily builds at 4pm Central and at that time, the build server comes to a screeching halt because all of them run at the same time. We’ve had to stagger them an extend the timeout limit on several because of how slow it gets. Team City instead runs one at a time, queues the others, and lets you prioritize the queue if you need to bump things up.
- Does more for you. First of all, it exports the source from the main repository cache for you. When building, you want to avoid working off the main repository cache since then you can get stuck with collisions on update, but with CC.NET, we always had to do the export and everything ourself. Team City takes care of and reverts the source to a clean state one each run.
- Artifacts and cross dependencies. In CC.NET, we always had a network share set up where we’d place built packages, but with Team City, they can be loaded back into the main site for storage and easily accessible. On top of that, you can place dependencies between builds and have the artifacts extracted. For instance, we have one built that fully packages a release every day. We have another build that our Selenium tests. We have a build dependency on them so that Team City extracts our latest package and the build script sets it up in IIS and runs against it. As time goes on and we get more of our subcomponents into Team City, ensuring all subcomponents stay up to date will be automated and far easier.
- Streaming build log. No longer do I need to wait for the build to be done to see what is going on. Team City can stream the build log to the browser, so I can see where its at, what is hung up on, or if it did something wrong that wasn’t an error, can stop the build and correct it.
- Easily customize builds. A while ago, we’d built a “preview build” and then a short while afterwards, realized there was an issue with the build. Not with the code, but just the build process. We needed to send an updated one, but wasn’t sure if the latest code was at a release-worthy state. Luckily, Team City makes it super easy. Right through the interface, I was able to kick off a new build of the same SVN revision as the earlier one. It also was intelligent enough so that in the history, it distinguishes it so someone knows it is different and in the description, says it is a build of an earlier commit and out of line with the other builds.
- Test history. We’ve just started pulling in our test builds, but one nice thing I’ve immediately notice is some of the rich reporting it has around test stats. For instance, it shows when a test started failing (if its been in multiple builds), allows you assign someone to be responsible, allows you to track a test’s history, and even identify problematic tests (probably ones that fail the most). You can even track the test duration and see it change over time.
Overall, would have to sum Team City up as just being incredibly refined.
I know a number of people who have larger Cruise Control setups than us, but overall Team City brings a lot to the table and the cost factor makes it a dead on winner. Team City can easily pay for itself just in terms of productivity. But on top of that, it is free up to 20 build configurations!
Trunks officially launched
This morning was looking at my blog and I realized I’d never posted about launching Trunks!
On Monday, I took the beta sticker off Trunks, making it officially available. Trunks has been doing quite while, and although it still has a small user base, I’ve been very pleased with its growth. Over the three months it was in beta, new users were slowly trickling in and even got a mention by Mike Gunderloy. There weren’t any major issues that came up, just a few bugs here and there. In that time, have added a few new features, refined the backend, monitored performance (even though its small, still important), and focused on stability of the systems.
Last week I was talking to a friend about Trunks and they were asking what was left in order to launch it… boiled down to adding diff support and the ability to pay for it (kind of important). After thinking “that’s all,” I figured I’d buckle down and finish things off. Also managed to fit in some UI tweaks and refinements, especially after cringing at the signup page I used to have.
If you haven’t already checked out Trunks, I definitely invite you to.

Papercut 2010.3.3 released!
Have been working on a new take on Papercut (details coming soon) when I noticed that there were several issues opened in Codeplex and a number of patches submitted. I’d forgotten to enable email notifications! So decided to sit down and felt some of them merited a new release. Release notes below.
This release includes a few bug fixes and updates, several of which were contributed patches (thanks!).
- Feature: Added support for embedded images (patch submitted by jasonpenny)
- Enhancement: Show an alert when trying to use port that is already in use (Issue #5405)
- Enhancement: Don’t show the options dialog in the taskbar (patch submitted by dukesb11)
- Fix: Updates to fix issues with multipart messages (Issue #4959, patched submitted by jasonpenny)
- Fix: Issue with async networking and not handling a disposed object (patch submitted by jasonpenny)
- Fix: Out dated URL references (Issue #5457, patch submitted by billrob458)
Two years with Ruby
Tonight I realized that its now been two years since I first started working with Ruby. Back in February of 2008, I’d posted about my first experiments with Rails. Lo and behold, its now been two years. I do say two years with Ruby though, not Rails. I’ve been using Merb for about the past year and a half. Although I have started messing around with Rails 3 and really like what I see so far.
So in the past two years, what have I done? Sadly, a lot of it is sorely behind and out dated, but take a bit of a trip down memory lane…
- The SkitchDav I originally blogged about, but now no longer use
- DM-DBSlayer. I was using it in a personal app, but the app didn’t need scale, so eventually removed it.
- DM-Paperclip. I really need to dust this off, it needs some TLC.
- Some hacking on Warehouse, which eventually led to my ideas for Trunks.
- Branches, which was basically a ruby port of Gitosis. I wrote it anticipating using it for Trunks so I could interact with the DB in Ruby. I did in the first incarnation of trunks, but am now on “Branches 2.0″ which was done from scratch and super simplified so it is Trunks-only and structured to do both Git and Mercurial. Would actually be nice to pull it out of Trunks and release it. Damn, another project for my list.
- Tigger. Really bad name. When I first wrote Trunks but was unsure about launching it, tried to redo the interface as a better read-only web interface to git repos. The app should still work… was on Merb 1.0.
- And of course, Trunks. Merb 1.1-pre.
And I’ve also had several apps that haven’t seen the light of day and were more for my personal use or tinkering.
- For a while I was into EVE Online and wrote an app to parse and process item reports from Eve Central. It allowed me to locate items that were selling under market rate quickly, compare prices across markets, and I could somewhat defer what items were selling most at different market hubs. Really geeky. Probably put several months into it. Merb app.
- Also wrote an app to track my sales by location, by item, and comparing sales volumes based on price as I played with prices. Merb app.
- And another for EVE Online… came up with the “Jita Mineral Index” which tracked mineral prices in the main market hub in the game. I left it up for several months after I stopped playing, until I found that the app that processed the emails from Eve Central broke and had like 200k+ unprocessed messages in its inbox. Merb app.
- Some time ago, was playing with different virtualization APIs and wrote an app that would provision and deploy virtual servers in KVM and in XenServer. I’m probably too much of a nut about virtualization. Mixture of stuff… Ruby, Nanite, Merb.
- A really basic Sinatra app to handle my domains that just have static pages. Rather than having multiple sites, I have just one and it determines which template to render based on the host header. Was my first Sinatra app.
And of course some other stuff on Github and Gist.
And I have some that will likely be coming soon:
- This, which I’ll likely blog about once I get a name for it and a domain. And update the incorrect launch date in the News part, oops.
- Was actually thinking of dusting off my original SkitchDav as a Sinatra app. What triggered me to write this.
- Also thinking of dusting off an app I prototyped a while ago involving Rack and Solr.
- Always got ideas brewing in my head… just a matter of parsing out which are really worth my free time.
All this Ruby has also helped me to grow so much more as a .NET developer.
- More languages you know the better.
- Exposure to new methodologies and mindsets, new more progressive community.
- Exposure to testing. Testing is far easier in dynamic languages, and grasping the concepts in a dynamic language makes it easier to apply to a static language.
- MVC. Thank god for MVC. Unlearned all the webforms crap and re-learned plain and simple HTTP and a logical structure for your app.
- Making programming fun again. Its nothing against .NET, but sometimes you need to break out from the familiar and learn something new to remind you why you love programming. Before Ruby, I was stuck in what I knew and don’t really think I was coding for fun much.
Migrating datacenters: How to forward traffic
I have some of my own datacenter space with a couple of servers that I use for a little bit of hosting that I do. This weekend, I’m finishing a migration and having done this type of thing a couple of times, thought I’d share a few tips.
First of all, one thing that is very nice to do, if you have a presence in both places at the same time, is to configure IP forwarding from your old site to your new site. While it is a best practice to set the TTL on your DNS records really low (mine are currently 60 seconds), ISPs don’t always honor the TTLs and some will be more aggressive with caching. As a rule, its usually 8-24 hours before you can really count on old caches being expired.
To combat this, forwarding any traffic that might be going to the old addresses to the new ones can be very helpful, and fairly easy to do.
There can be several ways to do this, but can often times end up more complicated. The pure and simple way to do it is to use an application called rinetd, which is basically an “internet redirection server”. You simple edit its configuration file, specify the old IP address and port, and the new IP address and port. Run it and you’re good!
I run ESXi on some of my systems, so I simply created a new virtual machine with a very basic configuration and installed Ubuntu on it. I gave it a base IP that I wasn’t going to be forwarding, installed SSH on it (to remotely manage it), and then went to town setting up what I needed forwarded. First, I added the IPs to be forwarded as aliases in /etc/network/interfaces:
auto eth0:0
iface eth0:0 inet static
address 192.168.1.111
netmask 255.255.255.0
Now, I need rinetd. On Ubuntu, it is readily available as a package, so just run sudo apt-get install rinetd and you’re set. Edit the /etc/rinetd.conf to list out how you want things forwarded:
# old ip old port new ip new port 192.168.1.111 80 172.16.1.222 80
Afterwards, all you need to do is restart networking and rinetd. So run sudo /etc/init.d/networking restart and sudo /etc/init.d/rinetd restart.
Few things worth noting. rinetd binds to the address/port you specify, so if you are trying to forward port 80, you can’t have something else bound to port 80 on that IP, such as a webserver. So if you need to forward something that you might have in use, you may have to tweak things. If you need to forward SSH, it might be best to configure SSH to use another port for a little while. Second, I’d sometimes just reboot the virtual machine instead of restarting networking. I’d migrate some stuff one night and have it forward for 24 hours, then next night migrate something else and have it forwarded. It’d sometimes get a little hairy adding/removing/reconfiguring aliases a lot, so I’d just reboot.
Another plus with rinetd is that a port of it exists for Windows! A download exists on its site and it is also possible to configure it as a Windows service using ServiceEx. I haven’t tried it myself, but I did find some pretty detailed instructions about configuring it on Windows.