The Disco Blog

Can you dig it?

Crowd Think Often Lacks Clarity

In case you missed it, InfoQ has an interesting analysis regarding hybrid mobile app development frameworks. They are profiling 12 tools and soliciting community feedback so as to make a ThoughtWorks-like technology radar. If you participate in the voting you are entitled to see the voting distribution.

What’s interesting (and not too surprising) about this analysis is that frameworks like PhoneGap or jQuery Mobile (and laughably JQTouch?) are leaning more towards adoption ready when compared to frameworks like Marmelade, Coronona or MoSync. But this radar lacks some clarifying dimensions – for example, if you want to produce a mobile website on a lot of different mobile platforms quickly, then PhoneGap is probably the way to go. But if you’re looking to create a mobile app, then the choice to use PhoneGap must be treated with extreme caution.

Mongoid Batch Inserts

In SQL land, all databases support batch inserts. Batch inserts are an effective and efficient mechanism to insert a lot of similar data. That is, instead of issuing x insert statements, you execute 1 insert with x records. This is much more efficient because the insert statement doesn’t need to be re-parsed x times, there is only 1 network trip as opposed to x, and in the case of transactions, there is only 1 transaction instead of x. When compared to x inserts, batch inserts are always faster.

As it turns out, MongoDB supports batch inserts! And just like in SQL land, Mongo’s batching feature is much faster at inserting a lot of data in one insert rather than x inserts.

For example, the Mongo Ruby driver’s insert method takes a collection; thus, you can insert an array of hashes quite efficiently. Even if you are using a ODM like Mongoid, you can still perform batch inserts as all you need to do is get a reference to the model object’s underlying collection and then issue an insert with an array of hashes matching the collection’s intended document structure.

For instance, to insert a collection of Tag models (each having 3 fields: name, system_tag, and account_id) in one fell swoop I can do the following:

Batch inserts with Mongoid model example
1
2
tags = ['a', 'bunch', 'of', 'tags'].collect { |tag| {name: tag, system_tag: true, account_id: id} }
Tag.collection.insert tags

In the code above, the insert takes a collection of hashes; what’s more, the insert is tied to the tags collection via the Tag.collection call.

Batch inserts are always faster if you have a lot of similar documents – in our case, we saw a tremendous performance increase when employing batching.

2013 Open Analytics Summit

On March 25, 2013, I’ll be speaking at the Open Analytics Summit in Washington DC; specifically, I’ll be discussing how the App47 team has used MongoDB as the backend of our enterprise mobile application management platform. We’ve learned quite a few things about Mongo over the last two years! In the process of growing from a few gigabytes of data a month to over a terabyte/month, we’ve found out first hand what Mongo is good at and what it’s not good at. I’ll be addressing a number of tips, techniques, and strategies – if you are a Mongo user or planning on being one, come on by!

Node.js in 3 Commands

A few short years ago when I started to explore Node.js, I remember the installation on my MacBook Pro required downloading the source, compiling and installing it, and then updating paths. And then you had to install NPM.

Since then, Node’s installation has been come tremendously easy and NPM is even bundled with Node. And yet, installing Node (and keeping up w/its rapid release schedule) is even easier with a nifty tool: Node Version Manager.

With Node Version Manager (or nvm) you can be up and running with Node in 3 easy commands.

Step 1: Download and install nvm.

downloading nvm
1
curl https://raw.github.com/creationix/nvm/master/install.sh | sh

Step 2: Reload your shell.

reloading .bash_profile
1
source .bash_profile

Step 2.5: Obtain a list of available node versions to install.

listing available node versions
1
nvm ls-remote

Step 3: Install your desired version of node.

installing node version 0.10.0
1
nvm install v0.10.0

After that’s done, execute a node -v to verify. Now wasn’t that easy? You bet!

The Bull’s Eye on Mobility: Mobile for the Masses

Since joining App47, I’ve been lazer focused on mobility; consquently, I’m pleased to announce that a new mobile development series has debuted on IBM developerWorks! The inaugural article, ”A gentle introduction to Android”, begins by exploring the mobile landscape and introduces how to get started with Android app development.

As the article summary states:

The mobile landscape is rich with promise, and Android is a viable and exciting platform for developers who seek a way in. This new series starts with an introduction to Android that is tailored specifically for Java developers just getting started with mobile. Learn about Android’s three-layer versioning system (and find out why it matters), then set up your development environment and build your first Android app.

So what are you waiting for? Check out ”Mobile for the masses: A gentle introduction to Android” and learn the ins and outs of Android development! Stay tuned for more articles to come and don’t forget to watch for mobile focused articles on this blog as well.

It’s a Question of Wow

Let me ask you a question: do you want to build a mobile website or a mobile app? If your answer is mobile website, then HTML5 is good enough. But if your answer is mobile app then you had better think about user experience. You see, the user experience bar has been set extraordinarily high by a number of stellar native apps. People expect to be wowed and if they aren’t, they won’t use your app. It’s that simple.

How do you wow someone? You make your app easy to use and aesthetically pleasing to the eye. And it has to work correctly consistently. Unresponsiveness, however minor, won’t do.

Can you wow someone with an HTML5 mobile app? Sometimes. But let me tell you: it’s not easy. Don’t think for a second that just because there are a gazillion developers who have an understanding of HTML and JavaScript, that anyone can build an app to inspire a wow. No, it’s a tricky business with HTML5 these days.

Yep, there are fewer developers out there that actually can code Objective-C or truly understand Android. They might be costly too. But the wow comes from native apps these days and it looks to be that way for some time. Native apps are close to the bone – they don’t have to rely on browser standards or shivs to work correctly 83% of the time. Coded correctly, they work all the time. They are responsive, fast, and can work offline without a lot of magic.

HTML5 is great for mobile web sites. Not mobile apps. Until HTML5 can produce a significant wow factor, your best bet is to go native. It’s that simple.

Everything You Need to Know About MongoDB

Are you new to MongoDB? Curious to see what’s interesting about it? Document-oriented databases like MongoDB are vastly different from relational databases in that they don’t store data in tables; instead, they store it in the form of documents. From a developer’s perspective, document-oriented (or schemaless) data is simpler and far more flexible to manage than relational data. Rather than storing data into a rigid schema of tables, rows, and columns, joined by relationships, documents are written individually, containing whatever data they require.

Among open source, document-oriented databases, MongoDB is often billed as a NoSQL database with RDBMS features. One example of this is MongoDB’s support for dynamic queries that don’t require predefined MapReduce functions. MongoDB also comes with an interactive shell that makes accessing its datastore refreshingly easy, and its out-of-the-box support for sharding and clustering (via replica sets) enables high scalability across multiple nodes.

Check out this IBM developerWorks’ Knowledge Path dubbed ”Discover MongoDB” – watch four videos, read a few articles, listen to a podcast and learn everything you need to know about MongoDB!

Testing Rails Migrations

I recently found myself searching Stackoverflow and Google for various techniques for automatically testing Rails migrations. I was surprised not to have found too much information though. While testing a migration is fairly straightforward (migrations are classes and you can easily invoke corresponding methods); the challenge can be setting models up properly. That is, migrations are a tool to update an underlying database to reflect changes in models – by the time you are writing a migration, the models already reflect what should be.

Accordingly, to test a migration, you need to set up your test with how things were and then run your migration and verify things have migrated. As it turns out, this is super easy to do with a document oriented database like MongoDB. For this particular project, we’re using Mongoid, which is an Object-Document-Mapper (or ODM) for MongoDB and we’re also using a nifty gem dubbed mongoid_rails_migrations, which facilitates writing Mongoid migrations.

In order to reflect the state of the underlying datastore before running a migration, I needed to remove a particular collection, which due to changes in our models, is automatically populated with meta data when various events occur (think relational trigger here, for example). As you can probably see, as this new collection doesn’t exist in production, all the existing data in production needs some corresponding default meta data to reflect the new requirements which brought this collection to life.

Accordingly, once I initialize my models and the corresponding collection is populated, I need to completely drop the collection. Then, I can run my migration and then verify that the previously nuked collection is present with all the required data.

In my case, I’m using shoulda in concert with Test::Unit, but the details of a test framework really don’t matter – in any case, you’ll need to load your migration, which can be done via a require statement like so:

Requiring a migration
1
require File.join(Rails.root, 'db', 'migrate', '20130217194234_member_app_roles_permissions')

In my fixture logic, I’ve initialized a few objects and related them, which automatically creates the aforementioned meta data collection; consequently, I need to do two things. First, get a connection to the underlying test datastore and then drop that collection.

Obtaining a connection and dropping a collection
1
2
db = @account.db
db['member_app_roles'].drop

Now I’m ready to run my migration – it’s as simple as invoking the class method up!

Invoking a migration
1
MemberAppRolesPermissions.up

Once the migration has finished running, I can then verify that everything is cool and copasetic. In this case, I need to go directly to the datastore because those objects in memory won’t reflect my changes just yet.

Asserting things worked!
1
2
3
4
5
6
7
8
member = Member.find(member.id)

assert_equal 2, member.member_app_roles.size
member.member_app_roles.each do |app_role|
  assert_equal 'admin', app_role.role
  assert_equal member, app_role.member
  assert_not_nil app_role.app
end

As a benefit of thinking through how to test a migration, you end up unveiling how you’d construct the migration’s down method. That is, in my case, to roll back, all I need to do is blow away the member_app_roles collection!

As you can see, testing migrations isn’t terribly difficult (probably a good reason why I haven’t found too much information about it); the key aspect is the logic that is applied to verify your migration actually worked. It should be noted that while I executed this test in the context of a document oriented database, you could certainly do the same in a relational database. For example, by dropping columns, tables, etc before running a migration. Either way, testing a migration is a snap. Can you dig it?

Circumventing Mobile UX Expectations

Recently, a buddy of mine pointed me to an interesting tweet:

New tool converts your Apple #iOS apps to #HTML5 http://dld.bz/cejxz #appdev

The article about this new tool, dubbed the ”Intel HTML5 App Porter Tool” suggests that because iOS apps are limited to one platform, HTML5:

represents an opportunity because it’s supported across a wide range of different devices and operating systems, so it enables the same code base to be reused across different app deployments.

While technically this statement is true – HTML5 is ubiquitous and you do end up with a single code base – HTML5 is the lowest common app development denominator and thus produces an underwhelming experience when compared to its native brethren.

Taking a native iOS (or Android) app and recasting it into an HTML5 app is like taking your beautiful Ferrari and trading it for a station wagon. The experience will never be quite the same.

Don’t get caught up in the HTML5 hype-cycle. It’s a great platform for mobile web sites, but if you’re building a mobile app, the UX bar has been set quite high. You cannot yet meet that bar with HTML5.