Wednesday, September 28, 2011

Amazon silk using webkit and SPDY

After reading the recent blog post by Amazon about their "cloud enabled" browser called silk, I went into a minor panic.  I couldn't find any immediate information about the rendering engine or any technical details about what they actually doing.  After some digging I uncovered some job postings that seem to confirm they are using webkit for their rendering and are leveraging SPDYon the network protocol layer.

This is great news for developers as webkit is already well established and most of us won't be immediately impacted by SPDY (well actually, your ajax experience might be impacted, but that's another topic entirely).  All told this isn't as big a technological change at the front end and is more of a story about amazon trying to use their infrastructure to make the mobile browsing experience better.  Frankly, this is a scaled up and modernized version of what blackberry did years ago (are they still doing that?).

NOTE to Silk team -- please implement an HTML5 native datetime picker on your device that doesn't suck so everyone else will follow.  This is a sore point for the mobile webkit experience right now and recurring problem that gets solved in a variety of "not so good" ways.

Friday, September 23, 2011

Using git in an agile environment

Git and most of the workflows I've seen on the internet are not designed (or well thought through) for most agile development.  By agile development I mean a small (1-10) team of professional developers all working together in short cycles (1-3 weeks) delivering functional software.

Why is git not designed for agile?  Because git, or more importantly, the workflows most readily apparent on the internet all focus on the idea of isolating changes or playing around with branches instead of getting stuff done.  This is great if you have a benevolent master who's sole job is to integrate disparate changes into a common code base (you know, someone like Linux Torvalds), but awful if you have a team of 10 people hacking away on a common codebase.  Aside from some very epic fails in the cvs and svn designs, git by itself doesn't really help in this situation.  I'd dare to say that git actually gets in the way 3x more than it helps.

To make matters worse, if you peruse the internet, you'll find a plugin called gitflow that canwill really make things bad.  It adds yet another layer of indirection and overhead that is totally unnecessary on a small team of professional developers working together in short cycles to deliver functional software (you'll notice that I've said the same thing again here).  Gitflow is great if you have lots of time to merge and integrate and otherwise play around with your tools, but not so great if you're on a small team of professional developers trying to work together in short cycles to deliver functional software... because it's just overhead.

I think I've made my first point about the type of team and type of goals that the  normal usage of git will cause problems with.  If you're not in that group and/or you like playing around with git, and/or you like sitting down at night with a copy of "pro git" and spending hours analyzing gitk diagrams... read the rest of this posting with caution because it's probably inflammatory and wrong in your world view.

First off... If you're working together writing a rails/struts/springmvc application, there are common files that everyone is going to be editing.  That's just the way it works, if you try to architect your solution by carving your application up into 10 pieces and give a piece to every developer, you're probably making a very big mistake.  The fact is, a version control tool is about SHARING CODE and software development teams are supposed to WORK TOGETHER, not in isolation.  Please repeat that sentence until you git it (hahah, I crack me up sometimes)...

Anyway, for MANY projects, especially small agile projects... branching should be a bad thing.  Every branch incurs the overhead of both keeping it up to date, but  also resolving conflicts as well as reintegrating (and testing) changes.  These costs are n^n as the team gets larger (actually, it might be n^n-1, maybe a math guy could help me out here?) and your objective should be to minimize them because they don't add value.

The simplest way to minimize these costs?  Have everyone integrate with a central repository (like github) and resolve incoming conflicts/test their code before pushing back to central.  If you follow that workflow, you're essentially using the central svn/cvs style coding on top of a decentralized tool, and there's NOTHING wrong with that.

So, how do you do it?  First, if you're using github, DON'T FORK, clone the repo to your local machine.  Once you've done that, follow this workflow (more  detail can be found here):

  1. write software and test it
  2. git commit -a -m 'My work here is done'
  3. git pull --rebase
  4. test and/or resolve conflicts
  5. git push origin 
  6. repeat


That's it... don't let the DVCS gods make you feel ashamed, just do it and all will be well.  There are certainly a few wrinkles that might happen in this workflow... notably, if #1 while you're fixing your rebase, someone else does a push, or #2 someone doesn't use rebase and is creating branches and merge commits.

#1 is easily fixable by perusing the interweb
#2 is a bit more tricky, but also fixable by perusing the interweb

In short, don't create branches on top of branches and screw around merging all over the place, rebase is your friend, use him wisely and all will be well.  Another note I will add is-- NEVER  do a "git push -f" (force push) in this mode.  You will screw with everybody on the team's head and they will likely need to start drinking early in the morning to figure out what is going on.

Wednesday, September 21, 2011

cross platform mobile development with phongap, rhomobile, and titanium

I've been working on a cross platform mobile application for keeping track of how much time I spend doing things. Basically a consultants helper to make sure I'm spending appropriate amounts of time doing the things that move me forward and keep me aware of how much time I'm spending doing things that aren't going in the right direction.
Anyway, having done mobile web development and knowing the pain there, as well as having put together a few android/iOs "hello world" applications, I did NOT want to go down the "build 3 different versions" road. I understand that there are compelling reasons to do this, but there aren't compelling enough to do it (in my situation).
Knowing that there are a number of solutions in this space, I narrowed it down to things that seem to have #1 the most innovation and #2 the highest potential to NOT be a dead end career wise. My list was narrowed down to titanium mobile,rhomobile, and phonegap. First off, titanium certainly has the best press corps in my opinion, the down side is that they appear to be going down the IBM path. That is, they're trying to build an "everything but the kitchen sink" heavyweight solution that is pretty off putting. In addition, the requirement to download proprietary development tools is just not where I want to go at this moment. While their solution looks very complete, I can't help but feeling it will end up being a dead end career wise. What I mean by this is that I think eventuall titanium will end up going the way of coldfusion - it will be widely used and very lucrative, but you'll be branded as a "titanium guy" for the rest of your career. For the reasons I mentioned, I actually downloaded the sdk, but didn't actually do any development using it.
Next is Rhomobile. One thing that excites me about Rhomobile AND phonegap is their distributed build system. This means I can actually build the cross platform components and NOT necessarily have the full SDK installed on my machine. Another upside to Rhomobile is that it uses ruby (a language I happen to like), but that upside quickly turns into a downside. I spent a number of hours trying to figure out how the browser components interacted with the ruby components and ultimately gave up. Rhomobile, I like the idea, but your solution is WAAAY too complicated and confusing. The other downside to Rhomobile is that same sort of "proprietary lock in" that I think will plague titanium. While I like the concept, I cannot get on board with rhomobile at this point.
Last, but certainly not least is phonegap. I actually used this for the first time almost a year ago and at that time I wasn't really impressed. An upcoming project I may take on had mentioned they're going to probably use this so I took another look. Holy crap! Not only have they made the barrier to entry almost zero, they have the simplest solution imaginable (given the current state of the art). Basically after signing up, you fork a github repo with the libraries pre-assembled (there aren't many), then start coding html and javascript... Once you're ready to deploy to devices, you push.. then log into their build server and hit "update"... a few minutes later you have a set of barcodes on your screen that allow you to deploy your application to blackberry, android, ios, webos, and symbian. I'm not sure how great the blackberry, webos, and symbian applications are, but the android seems to work very well and i'm going to test ios in the near future.
Using phonegap in addition to ripple mobile emulator in chrome makes me super productive and I can use the development tools of my choosing. For now, phonegap + ripple + whatever text editor are my tools of choice and I highly recommend trying them out. As for rhomobile, guys... I'm rooting for you, but it's just too complicated and I don't have enough spare time to figure it out. Titanium.. I think you have a market in the corporate enterprise space, but you're likely to not attract many indie guys as you just seem tooo... heavy.

Tuesday, September 20, 2011

What's the difference between macports and homebrew?

Anyone using a mac for software development has probably run into the need for some gnu/open source software that isn't pre-packaged. One of the great failings of Mac OSX is it's lack of a real package manager. Luckily, users stepped up and built some solutions: Fink, MacPorts, and HomeBrew.

I've never used fink, but I hear it's pretty good. Being also a debian/ubuntu guy, I'm familiar with apt-get so it's probably a decent tool... but having no direct experience with it I can't really comment.

This brings me to the two tools I HAVE used: Macports and HomeBrew. I started off with macports because it was the one that had the packages I was looking for. On advice from folks I was working with (I believe the comment was "why are you still using macports, everyone is using homebrew now"). I downloaded and started using HomeBrew, but frankly, I'm unimpressed.

As far as I can tell, the only reason anyone would use homebrew is if they stumbled across one of the web sites/blog posts with the raving fanboys flipping the bird to all the uneducated macports users. When digging around, I did find this fairly objective blog post which leads me to believe that homebrew is really...not that different. The biggest difference I see is that macports has almost everything I want, whereas homebrew is missing huge quantities of useful software, so I ended up requiring macports anyway.

I like the idea that homebrew will apparently use binary packages in some situations and frankly, I don't understand why that isn't the standard. After all, debian and redhat have been doing this for years and it's much more efficient that wasting your user's time recompiling for a tightly controlled platform. Anyway, my advice is macports works for me, homebrew also works, and they seem to both work together... so it really doesn't matter which one you use, but you'll still need macports anyway because homebrew is missing about 6000 packages that are already in macports.

Tuesday, September 13, 2011

Using Devise for authentication in rails 3

I recently started a new Rails 3 project and was going to use devise for authentication. While very powerful, the documentation was a touch confusing for me and all the other blog posts kept confusing me. What follows are my steps to get up and running with a minimum of effort and thinking.
Step 0, put devise into your Gemfile and run
bundle install
Next, Generate the devise install scripts
$ rails generate devise:install
Devise will spit out:
create  config/initializers/devise.rb
create  config/locales/devise.en.yml

===============================================================================

Some setup you must do manually if you haven't yet:

1. Setup default url options for your specific environment. Here is an
example of development environment:

config.action_mailer.default_url_options = { :host => 'localhost:3000' }

This is a required Rails configuration. In production it must be the
actual host of your application

2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:

  root :to => "home#index"

3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:

<p class="notice">
<%= notice %></p>
<p class="alert">
<%= alert %></p>

===============================================================================
Gotcha number 1 is that you need TWO entires in routes if you want to enable auto sign up. In addition to what's described above, you'll also need the following line in your routes.rb if you want to enable this:
  devise_for :users
Next, generate the active record files for your User account (I used User, why use anything else?).
$ rails g active_record:devise User
Which spits out the following:
create  db/migrate/20110831002655_devise_create_users.rb
create  app/models/user.rb
invoke  test_unit
create    test/unit/user_test.rb
create    test/fixtures/users.yml
insert  app/models/user.rb


After that, migrate your databse
$ rake db:migrate
==  DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
-> 0.0112s
-- add_index(:users, :email, {:unique=>true})
-> 0.0007s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.0006s
==  DeviseCreateUsers: migrated (0.0128s) =====================================
Generate a controller for your home page (optional if you've got another controller).
$ rails g controller home
Which spits out this:
create  app/controllers/home_controller.rb
invoke  erb
create    app/views/home
invoke  test_unit
create    test/functional/home_controller_test.rb
invoke  helper
create    app/helpers/home_helper.rb
invoke    test_unit
create      test/unit/helpers/home_helper_test.rb
remove app/public/index.html < this is important!
rm app/public/index.html
edit app/controllers/home_controller.rb and make it do something: NOTE: ;we've added the devise before_filter to require login/signup, this is what tells devise that the controller should be secured.
class HomeController < ApplicationController
  before_filter :authenticate_user!
  def index
    render :text => "Welcome #{current_user.email}!"
  end
Next generate the devise views. I don't think this is strictly necessary, but I'm assuming you'll want to customize these after you get going.

$ rails g devise:views
Output should look like this:
      invoke  Devise::Generators::SharedViewsGenerator
      create    app/views/devise/mailer
      create    app/views/devise/mailer/confirmation_instructions.html.erb
      create    app/views/devise/mailer/reset_password_instructions.html.erb
      create    app/views/devise/mailer/unlock_instructions.html.erb
      create    app/views/devise/shared
      create    app/views/devise/shared/_links.erb
      invoke  form_for
      create    app/views/devise/confirmations
      create    app/views/devise/confirmations/new.html.erb
      create    app/views/devise/passwords
      create    app/views/devise/passwords/edit.html.erb
      create    app/views/devise/passwords/new.html.erb
      create    app/views/devise/registrations
      create    app/views/devise/registrations/edit.html.erb
      create    app/views/devise/registrations/new.html.erb
      create    app/views/devise/sessions
      create    app/views/devise/sessions/new.html.erb
      create    app/views/devise/unlocks
      create    app/views/devise/unlocks/new.html.erb
Run your app and you will have auto-signup and authentication enabled. For more infomation about how to further customize your config see the devise web site.

Monday, September 12, 2011

defining IaaS, PaaS, and SaaS for cloud computing

Looking through cloud literature, it seems we've run out of three letter acronyms (TLA), so we're now using four letter acronyms (FLA?). Chief among these are the "as a service" acronyms which describe what level of stuff is handled by the provider. Wikipidia has some sort of explanation buried in the cloud computing page, but I thought I'd give the abridged version.

At the lowest level is "Infrastructure as a Service" (IaaS): You get a virtual server with connectivity to the internet. Examples are Amazon ECS and Rackspace Cloud. In these offerings, you can install almost anything you want (you typically get root access in some manner) and can even install the operating system of your choice. This is a good choice if you're a sysadmin who just doesn't want to muck around with physical hardware.

The next level up is "Platform as a Service" (PaaS): You get some sort of development platform hosted remotely and you have a mechanism to write and deploy applications that run on that remote platform. Often you cannot log onto the server directly and you are sandboxed into a virtual environment with pretty stringent restrictions about what you can do within it. Examples of this are Heroku for ruby and cloud bees run@cloud for java. This type of stack is good for a developer who needs to deploy an application, but doesn't know anything about the underlying technology.

At the highest level is "Software as a Service (SaaS): This is a hosted application that you simply use. Examples would be things like Lucid Chart or Gliffy. You just use this stuff and don't have any software installation or maintenance tasks.

A few providers blur the lines between IaaS and PaaS by offering hybrid solutions. An example of this is Engine Yard who provides what really is IaaS, but is largely centered around the ruby/rails platform. Amazon Elastic Beanstalk is an EC2 based java PaaS that also has more flexibily that something like run@cloud. I would say these last two are probably the most flexible PaaS solutions, but come with a bit more added complexity. They're probably the best for production deployments, but might be overkill for small applications with a limited user base.

Friday, September 9, 2011

Another Ruby 1.9.2 gotcha hashes are not arrays

In ruby 1.8.7, the following works

Michael-Mainguys-MacBook-Pro:~ michaelmainguy$ irb
ruby-1.8.7-p352 :001 > foo = {"foo","bar"}
=> {"foo"=>"bar"}
ruby-1.8.7-p352 :002 > foo["foo"]
=> "bar"
ruby-1.8.7-p352 :003 >


In 1.9.2, it fails rather curiously.

Michael-Mainguys-MacBook-Pro:~ michaelmainguy$ irb
ruby-1.9.2-p290 :001 > foo = {"foo","bar"}
SyntaxError: (irb):1: syntax error, unexpected ',', expecting tASSOC
foo = {"foo","bar"}
^
(irb):1: syntax error, unexpected '}', expecting $end
from /Users/michaelmainguy/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `
'
ruby-1.9.2-p290 :002 >


Matz/et-al, get it together... this is a pretty significant change and probably warrants a deprecation warning instead of a mysterious fail that in no way indicates what is really happening. This will seriously dampen adoption of the 1.9.x series of ruby for newbies who used the hash constructor the old (arguably incorrect) way.

Newbies, if you try to upgrade to ruby 1.9.2 and you get these strange error messages.... it means you where trying to create hashes by passing comma separated values... if you really wanted to create a hash the ruby way would be

foo = {"foo"=>"bar"}

or, for an array
foo = {"foo","bar"}

by doing {"foo","bar"}, ruby was helpfully (in 1.8.7) translating your call into
foo = Hash.new(["foo","bar"])... note, in the cases I'm finding this, the folks really wanted an array, but because it "kinda" worked, they didn't realize what had happened.

Maven central and rubygems.org

I was thinking about some of the differences between the ruby and java ecosystems and one comparison point I thought would be telling was how many packaged, open source, third party components are readily available. From my perspective, the current "way to get things" in java is maven, and the equivalent in ruby is a ruby gem. Conveniently, there is a central repository for both of these things, maven.org and rubygems.org.

It's interesting that they have almost an identical number of components: Maven has 29,815 and rubygems has 28,078. Of the top 10 downloaded from each, 1/2 of the maven artifacts are components to interact with maven repositories. Rounding out the maven list are: junit, commons-lang, and commons-collections. On the rubygems side, ALL of the top 10 are related to or used by rails.

I've heard folks say that ruby/java has more components available, but it just doesn't seem that way when looking at the numbers. I've yet to find a library that is NOT available in ruby/gems or java/maven.

Facebook/twitter integration? both have in spades...

library to simplify communicating over a serial port, it's in there...

Frankly, the rumors of one or other of these ecosystems have more open source component support are largely false. For MOST applications, I'm comfortable saying you cannot go wrong with either of these. To me, ruby seems to get more productivity from developers, but java isn't going anywhere soon.

I DO have a question though, is there something similar to maven and ruby gems for C#?