Boring is Best

April 17, 2014 in Soapbox |

I really like this blog post by Matt Jaynes about building solid business on proven technologies:

I struggle with this myself, the desire to use the latest and greatest tech in our systems at, but fortunately I have some really smart people around that help me realize when that’s not the best idea for the business.

It Requires Super Human Discipline to Write Readable Code in Callbacks

February 1, 2014 in Computer Science, Development, Open Source, Soapbox | Tags: , ,

Callbacks can be messy, as Guido Van Rossum said in his recent asyncio talk (@ 56:27 in the YouTube video):

“It requires super human discipline to write readable code in callbacks and if you don’t believe me look at any piece of JavaScript code.” ~ Guido Van Rossum

Fortunately you don’t have to write callbacks if you don’t want to. You need only look to Tornado and Motor

tornado and motor

Python has some neat features that let allow generators to be used as coroutines. The Tornado Web Framework includes decorators to make this dead simple. For me, the biggest drawback to using Tornado was the lack of a good asynchronous db driver. Using a blocking db driver sort of defeats the purpose of a non-blocking web server. Fortunately for those of us who don’t love writing callbacks, now there is a good solution.

Motor is a first class asynchronous MongoDB driver written by Jesse Jiryu Davis from MongoDB that will soon take advantage of Futures to present an easy to use, but still asynchronous, interface with MongoDB.

Jesse announced some changes that make using Motor even easier by incorporating Futures into the syntax, just like recent versions of Tornado. We are waiting on MongoDB v2.6 RC, which roadmap indicates will be released on 2/11/14 and the associated version of PyMongo.

In anticipation of this release, I thought it would be fun to look at just how far asynchronous db drivers for Tornado have come. Despite Jesse’s warnings that we should wait until the changes are official, we’ve been using these techniques at to supercharge developer productivity and increase clarity in our asynchronous code.

In the Beginning

When I started using Motor v0.1 about a year ago this is what trivial DB access looked like for a simple handler that returns some JSON:

If I only ever had to make one db call, and only had to write one callback handler this would not be so bad. The problem is that in reality I need to make several db calls, and may need to wait until two or more are complete to do anything useful. The callbacks get out of hand quickly.

The worst problem is that debugging becomes a nightmare of epic proportions. The entire reason we use Tornado is to enable long-polling with lots of connections at the same time, and it becomes very hard to tell exactly where the problems are when lots of connections are active at the same time. Most developers (myself included) rely on stack-traces to debug our programs, but with callbacks like this you can kiss that nice stack-trace goodbye.

The Present

Motor v0.1.2 has come a long way since that time. Today a trivial DB access looks like this:

Technically you could also write it like this using motor.Op:

This is much, much better than before. Tornado’s tornado.gen module does a great job putting together a “stack-trace” when an exception is thrown and while this is certainly acceptable and useable, it still feels a little clunky. Why do we have to write motor.Op for example?

The motor.Op class exists because motor has a forward looking maintainer who was planning for the Future.

The Future(s)

disclaimer – this api is not released for Motor yet. It will come out with Motor v0.2 along with MongoDB 2.6 RC0 and PyMongo 2.7.

With Futures, we get to write the same thing like this:

The cursor.to_list method returns a Future directly and yielding the Future blocks this coroutine, returning control to the event loop, until the result is ready. It does not get any easier than that.

Developer Cycles are Precious

For many projects the most expensive component is the time put in by the developers, or as I prefer to call them, developer cycles. One of the main reasons we use Python is for the expressiveness of the language. In my experience we can ship more features that our customers want, more quickly by developing in Python than we can in any other language.

Tornado and Motor are making it much easier to deploy asynchronous web servers than it has been in the past. The new AsyncIO library will likely continue to accelerate that trend and that’s a good thing because I really don’t have time to write a bunch of callbacks.

What business needs are you solving with asynchronous web servers?

How-To Setup DNSMadeEasy Dynamic DNS on a Synology

September 21, 2013 in How To, Knowledge Base | Tags: , , ,

I had a lot of trouble finding any help to get Dynamic DNS (DDNS) set up between a Synology NAS (a great product!) and DDNS service so I thought I would post the solution that I worked out in case anyone else was looking.

1. Set up your DDNS domain on

DDNS setup on

The wrinkle that throws in the mix is that instead of the domain being updated, they use a unique ID number that’s generated when you save a record with the “Dynamic DNS” box checked.

After creating the record keep track of the password and the ID. You’ll need them later.

2. Add the DDNS provider for on your Synology NAS

If you open the DDNS control panel on your Synology (Control Panel > ezCloud > DDNS) you will notice that there is no option on the service provider menu.

Synology DDNS control panel

To add the Service Provider you need to SSH into the terminal. If you need help setting up terminal access check out this tutorial on the Synology wiki.

Once you have terminal access use vi to edit the /etc.defaults/ddns_provider.conf file with this command.

$ sudo vi /etc.defaults/ddns_provider.conf

The vi editor can be found on almost every POSIX system. It can be confusing for people who have never used it before, so if you need help with vi check out this cheat-sheet and tutorial.

Add the entry to the end of your ddns_provider.conf file as shown in the following Gist on Github:

We are actually using the same provider as DynDNS and only using the “hostname” variable to support’s “id” variable. I was a little concerned that the Synology would do some sort of validation on the HostName field and bounce the string of numbers as invalid. But fortunately they don’t and we can use that field to supply the ID without any further customization.

Save the file and reopen the DDNS control panel on the Synology.

3. Setup DDNS on your Synology NAS

Now you should have the option in the “Service Provider” field. Put your “Dynamic DNS ID” from into the “Hostname” field. Use the email address associated with your account for the “Username” field, and the “Dynamic DNS Password” from the record in the “Password” field and “Confirm password” field. Hit apply and if your status says “success” you are in business!

complete DDNS setup on your Synology

Netflix Parental Controls Worked!

July 13, 2013 in Soapbox | Tags:


I just needed to adjust my Netflix parental controls to watch the new show “Orange is the New Black” and I was dreading it because usually there is some message that says it may take up to eight hours to actually update.  This is usually the worst, but this time there was no warning about it taking 8 hours to update, and just 30 seconds after updating the settings on the computer I was able to watch the show!

Much better Netflix! Now we just need to be able to bypass the settings in any client (like AppleTV) by putting in a code or something instead of having to use the computer.

Startup makes Step-by-Step Guides Easy

July 11, 2013 in Reviews, Startups | Tags:

I find my self making these in email form all the time to send to people (family/friends/customers) about how to do things on the internet. It’s always been the easiest way that I knew of.

Now there is a new start up aiming to solve the problem:

Their app is super simple and makes it easy to quickly create step-by-step instruction guides to share. I love it, and I can see myself using this a lot.

<< more posts