Thursday, 8 November 2012

PDF.js and the Rails Asset Pipeline

is a cool javascript library that lets you display and do stuff with files directly in the browser. Unfortunately, it doesn't play well with the , or more specifically  (the default library for the asset pipeline). The problem appears when you precompile your assets for production and comes in the form of a syntax error in your javascript complaining about Octal literals.

The only solution we could manage was to turn off javascript compression when using PDF.js, but it might be that one of the other javascript compression libraries wouldn't generate the same issue.

Wednesday, 17 October 2012

Meteor.js on appfog revisited

Update 4/12/12: Appfog do now provide node 0.8, so my previous method of deploying works again.

Previously, I've written about deploying a application on . Unfortunately, meteor have recently released updates (0.4.1 and 0.4.2) that require 0.8 instead of 0.6. Appfog only supply node.js up to 0.6, meaning that until Appfog updates its stack, applications using recent versions of meteor don't seem to be deployable there.

Until that time, I'm using the hosting available directly through meteor.js for my application demos.

Tuesday, 9 October 2012

Using Amazon to scale JMeter

Most of the art of is discovering the right question. Once you know the question, the right approach almost always becomes clear.

For example, when we wanted to know how a app scaled, we picked . This worked well, producing the solid statistical evidence we were searching for, to be graphed and digested within a report.

Last month, we were asked to load test an application, to discover whether the audience could be safely let loose to play at a demo: Would the user experience be good enough at the expected load?

For subjective criteria, hard numbers are often tricky to interpret and may be misleading. Loading the system, then allowing users to evaluate the perceived performance is often a more revealing route. simulates complex user interactions well, so running one scripted instance per expected user seemed a promising strategy.

A good plan in principle, but one that needed 40 spare machines and big fat pipes. Time for .

Taking advantage of 's free tier, we opted to avoid the API learning curve by hand crafting.

  1. Through the web interface we
    • created vanilla Ubuntu images, and
    • distributed across the world, avoiding the per-region limits.
  2. Installed (JMeter and the load simulation) over ssh, scripting in multi-threaded Ruby to avoid IO bottlenecks.
  3. Started the simulations.
  4. Played with the app, evaluating subjective performance at load.
  5. Remembered to destroy all instances in every region

All very smooth :-)

Saturday, 29 September 2012

TDD with jQuery thoughts

I've recently been redeveloping a -heavy section of a project without any frameworks other than . To do this, I've been doing heavily with , but I'm not very happy with how I've managed to isolate the tests from the DOM and jQuery manipulation. My current process is to inject a 'fake' jQuery into the application constructed of Jasmine test spies, which works well enough but doesn't give very good granularity on ensuring that the jQuery calls have been made on the correct objects.

I'm curious as to what other people have done in similar areas. We now have > 300 tests on the javascript in this project, of which my new development currently constitutes about 100. The test suite as a whole (and tied to the DOM with jQuery) takes  ~2 minutes to run, but my new isolated tests run in ~1s so I'm interested in pushing the isolated approach forward for unit-testing. I could make my fake jQuery more feature-rich and able to track more detail, but I'd like to know what others are doing in this area before potentially reimplementing something that already exists.

Monday, 24 September 2012

jsPlumb

 is a pretty cool library for 'plumbing' a web page. It allows the drawing of arbitrary connectors between elements using straight connectors, style connectors or some nice-looking , giving some effects like this:
Screenshot of the jsPlumb jquery demo


I've been using jsPlumb in a recent project to draw some fun in conjunction with and my thoughts on jsPlumb are very positive. jsPlumb is fast to load, draw and redraw connections, it integrates with various different JS frameworks and it's pretty simple to use. About the only criticism I have is that it would be nice if you could influence the connection routing with a bit more precision, or simply have the ability to set up some elements that the connector should try to avoid.

Integrating the library with meteor.js was as easy as placing the jsplumb plugin file into the client/lib directory of the project.

Monday, 17 September 2012

RSpec with Turnip on Gentoo

is a cool extension, bring the goodness of Gherkin . But - like Gherkin - it's sensitive to shell encoding. I run , so to fix Encoding::InvalidByteSequenceError I use

export LANG=en_US.UTF-8

Thanks to stackoverflow

Thursday, 13 September 2012

Meteor.js on Appfog

is a great framework but it can be a little problematic to deploy somewhere other than the hosting provided by , such as the provider .

First was the task of getting the environment variables from Appfog to match up to the ones expected by Meteor. Meteor uses MongoDB, so first I added a MongoDB service on appfog. This is done easily by clicking on:


And selecting the MongoDB service:



This gives you MongoDB, but unfortunately the environment variables it exposes to your application aren't in the form that Meteor expects. To solve this, I added the MongoHQ add-on. Similar to before, I went to the add-ons section:


And selected the MongoHQ add-on:


I got a suitable URL environment variable when I added the 'MongoHQ' add-on, but the URL was under the name $MONGHQ_URL instead of $MONGO_URL. This is quite easily solved by going to the environment variables:


And setting up the following variable:


I also also set the ROOT_URL environment variable for my application as I wanted to generate absolute urls from meteor.

Previously, I also needed to set the PORT environment variable to $VMC_APP_PORT but this no longer appears to be necessary. If it is necessary for future deployments, the same process is used as for the MONGO_URL variable.

After the environment was correct, I encountered issues from the fibers package bundled with meteor. This was solved by removing the bundled package and reinstalling the fibers package from NPM with the bundled code. As this is needed each time, I wrote the following short script to automate the process (and also store the code that was released).

With this script in place, I can now deploy to Appfog reliably whenever I need to, without having to remember a set of file modifications.

Thanks go to http://blog.philkershaw.me/2012/06/deploy-meteor-to-appfog.html as the starting point for my deployment.

Wednesday, 12 September 2012

Internet Explorer Console Shim

Chrome is my weapon of choice when developing rich CoffeeScript and apps. This means shaking out all those little differences with towards the end of a project, and learning to live with all sorts of foible.

Turns out that that IE doesn't always play well with console. In particular, on IE9 calling console.debug fails with

Object doesn't support property or method 'debug'

Since console.debug is deprecated, I took this opportunity to grep and replace console.debug calls with console.log but its wise to remember to add the for troublesome older versions.

Tuesday, 11 September 2012

beforeunload events in Internet Explorer 9

is my weapon of choice for development. This means spending a little bit of time with when development's almost over, learning to play with its little ways. We were taking beforeunload to display a dialog whenever the user risks losing data by navigating away — but only then. IE9 (oddly) displays null in a dialog when null is returned from beforeunload. Returning undefined instead means harmony amongst browsers. Another little trick to add to the playbook...

IE9 on Rails in Development

The is one of my favourite 3.1 features. Assets — such as and files — are served as written in development mode. As a default, this is spot on but when debugging a rich app on , I found some tuning needed. In particular, IE9 has a hard limit of 31 stylesheets. In this case, it's useful to switch on asset compilation in development. Read on to see how...

is a cool plugin for drawing sparklines — small, in-line graphs. This library uses css injection. In development mode, IE9 raised an Invalid argument error when this was called. A little bit cryptic, but after a little digging, the cause turned out to be that hard limit. Time to tinker.

To serve fully processed assets in development: edit config/environments/development.rb, setting

config.assets.debug = false

Thanks Dennis Reimann for his clear example.

Thursday, 9 August 2012

Tidy Assets on Rails

The 3.2 asset pipeline is great, but it's good to keep that pipe clean and tidy. Reduce the clutter, and everything is much easier to find. Factoring out assets into gems DRYs (as well as tidies). With rails plugin new, this is now quick and easy. Thanks to RakeRoutes for crafting a fine step-by-step introduction.

Monday, 30 July 2012

RABL on Rails

There are plenty of ways to output from . So, when it was time for an existing app to move on from to_xml to support a richer API we were able to go shopping...

Following our Agile principles, we focused only on what we needed today. In this case, we went looking for an solution with these qualities:

  • concise
  • quick
    • to configure
    • to integrate
    • to learn
  • and readable.

measured up admirably. Kudos to nesquena and the rest of the RABL crew.

Is RABL the ultimate mapper? Maybe it is, but I think it more likely that there's ...

Thursday, 12 July 2012

Remember to clear requests between jasmine-ajax tests

We use for . To , we rely on to spy, mock and fake. A basic usage pattern is to jasmine.Ajax.useMock() then check mostRecentAjaxRequest(), but remember to clearAjaxRequests() to avoid inconsistency (when running as part of a larger test suite).

Taking a look at the source, clearAjaxRequests() is not called within the code. When running several tests are run in the same browser page, stale requests from previous tests may be returned by mostRecentAjaxRequest().

So, instead of jasmine.Ajax.useMock() then check mostRecentAjaxRequest(), adopt this pattern:


  beforeEach ->
    clearAjaxRequests()
    ...

  afterEach ->
    ...
    clearAjaxRequests()

  it "should save the JSON data using Ajax", ->
    jasmine.Ajax.useMock()
    ...
    request = mostRecentAjaxRequest()
    ...

Tuesday, 3 July 2012

CoffeeScript and the Curious Case of the Missing Bracket

Over the last month or two, I've grown to admire . This little language encourages developers to drop braces, sprinkling liberally around enabling . But there is one area where I think a little more would help a lot.

I sometimes find it useful to think of as just a functional language dressed up in someone else's Object Oriented clothes. Passing a function (rather than its value) is as simple as dropping its braces. So, for example alpha = bar.foo assigns the function foo on bar to alpha. Use alpha = bar.foo() to assign the value instead.

Objects and classes in CoffeeScript feel more natural, yet bar.foo still refers to the function foo. Intuitively, this feels wrong, and the only reason I can fathom for introducing this inconsistency is compatibility with JavaScript behaviour. This price seems too high for such little gain.

I suggest that, in CoffeeScript, bar.foo should call foo on bar with no parameters (just like bar.foo message passes message to foo on bar), and special syntax be introduced for function passing: bar.foo! perhaps...

Wednesday, 20 June 2012

A Rhodes Journey - Getting started with RhoStudio on OSX Lion

is a cross-platform open source mobile development framework that is  by . in some aspects of development. Rhodes was developed by RhoMobile, which was recently acquired by 

We started checking out Rhodes a year ago when using Snow Leopard as a development platform, and developed some trial apps. At that time, Rhodes used to be a simple gem that could be downloaded using the compatible Ruby (v 1.8.7) and rvm. Since I recently upgraded to Lion, I thought I'd give Rhodes another spin to see if it had changed. Indeed, I found that RhoMobile has grown by leaps and bounds, and that Rhodes is now a small part of a much larger scheme of things: Rhodes now ships within  which includes, apart from Rhodes, an IDE called  for developing RhoMobile applications, and two other frameworks called  and .

In this post I'll explain how I went about setting up Rhodes 3.3.3 from the RhoMobile suite and running the sample APIs app for Rhodes (included with the  RhoStudio installer) on iOS and Android simulators using the RhoStudio IDE.

Installing the Prerequisites

XCode

First off, since I wanted to start developing for iOS, I needed to download and install the from the .

Next, to run iOS aps on OS X I had to install the relevant simulators. These were not bundled with the XCode and had to be downloaded within XCode by going to XCode > Preferences > Downloads.


Here, we select the relevant iOS device simulators and XCode command line tools, which is a prerequisite of installing on OS X.

Note: if you don't want to develop for iOS and still want to install RVM (without installing XCode, as it is a heavy download), then you might need to install the to proceed.

Android SDK

In order to develop for Android, we need the and . These need to be downloaded and unzipped at a convenient location, which will be needed later to configure Rhodes and RhoStudio.

RVM and Ruby

Next, ensure that you have RVM and Ruby version 1.9.3 installed on your Mac. There is a step by step guide available . In my case I used RailsInstaller for installing Ruby on Rails, which also installed RVM. If you prefer GUIs then you may want to use  for managing RVM, rubies, gemsets and gems on your Mac.

Java Development Kit (JDK)

Rhodes also requires a JDK. For Lion, we need to install .

Installing RhoMobile Suite, RhoStudio and Rhodes

Now we are ready to download the Rhomobile suite installer dmg file from . Once downloaded, mount the dmg. 

Here, you can choose to proceed with installing the the entire suite provided by running the 'install gems on rvm' script file. However, I wanted to install only Rhodes, and thus, installed only the relevant gems using the following commands in Terminal:

gem install rhomobile-debug
gem install "/Volumes/Motorola RhoMobile Suite Installer/.gems/rhodes-3.3.3.gem"
gem install rhodes-translator

Next, copy the "Motorola RhoStudio.app" from the dmg into the Applications folder of your Mac and launch it from Applications. Upon launching, RhoStudio requests a workspace path that can be specified to a location of choice. Note that the Rhodes installation guide suggests that one shouldn't add a path with spaces as it causes problems with RhoConnect applications.

We need to configure the android SDK path in RhoStudio for it to build for android. Go to  RhoStudio > Preferences > RhoMobile > Android and add the paths for both SDK and NDK in relevant spaces. Click OK.

Building and Running the sample APIs application

Great, almost done now! 

Within the Rhomobile suite installer downloaded earlier, go to samples and copy the rhodes-system-api-folder to your workspace folder specified earlier. In RhoStudio, import the project by selecting File > Import > Existing Project into workspace. Choose the root folder as the workspace directory to see the project in the list. Select the project and click Finish. The project should now be listed in the Project Explorer.

Using the Android simulator

Before you can run the project on Android, you need to install the relevant SDK and Google APIs. To do so go to <android-sdk-macosx>/tools and run the file called 'android'. This should launch the Android SDK manager. Here we need to select the android versions that we want to build for. At the time of writing this post, the build.yml file is configured for android 3.0, which is what we will select in the SDK manager and install. 

After the installing the SDK platform, we also need to install the 'Google APIs' displayed under the installed SDK in the SDK manager. This is used by some Rhodes libraries in the kitchensink project. 



In order to run the project, go to Run > Run Configurations...  and create a new configuration by double clicking RhoMobile Application. Select the platform as Android and Simulator type as Simulator. Make sure that Project name says rhodes-system-api-samples. Click Run to give it a go.





Note: If it fails with a message requesting you to run 'set-rhodes-sdk' then do so in the project directory in the terminal and try running again. The application takes between 2 to 5 minutes to launch on an android simulator. 

Using the iPhone simulator

To run for iPhone create another run configuration and this time choose the Platform as iPhone. Click on run to start building for iPhone. Once built, the studio will launch the iPhone simulator with the application loaded.  

All Done!

This concludes a walkthrough of how to set up Rhodes and RhoStudio on Mac OS X Lion.

We can now proceed to creating Rhodes apps for both Android and iOS platform with (hopefully) less effort than writing apps in separate native environments. 

Thursday, 7 June 2012

A Scope Gotcha In CoffeeScript

I think a , and — after developing with it throughout May — have grown to like it a lot. However, hidden amongst all the smooth elegance are a few rough edges, to confuse and cut the unwary. Like me. This is the story of a small scope that caught me out twice.

Thanks to , I might implement a widget to manage a list of items a little like this, and when the user clicks the fat arrow sets a allowing an easy call to my new object.

class Foo 
 constructor: ->
   @items = []
   
 doSomething: ->
 
 buildList: ->
   $ul = $('<ul/>')
   for item, index in @items 
      $li = $('<li/>')
      $li.on 'click', =>
        $li.addClass 'active'
        @doSomething()
        false
      $ul.append $li

Except this doesn't quite work. To see why the active class ends up on last list element, take a look at the compiled :

var Foo;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Foo = (function() {
  function Foo() {
    this.items = [];
  }
  Foo.prototype.doSomething = function() {};
  Foo.prototype.buildList = function() {
    var $li, $ul, index, item, _len, _ref, _results;
    $ul = $('<ul/>');
    _ref = this.items;
    _results = [];
    for (index = 0, _len = _ref.length; index < _len; index++) {
      item = _ref[index];
      $li = $('<li/>');
      $li.on('click', __bind(function() {
        $li.addClass('active');
        this.doSomething();
        return false;
      }, this));
      _results.push($ul.append($li));
    }
    return _results;
  };
  return Foo;
})();

Oops - $li is defined right at the top of buildList. The context will contain the current value, from the last iteration.

There are several ways to improve this code and make this problem go away. One easy technique is just to factor out a method to build the list item.

class Foo 
 constructor: ->
   @items = []
   
 doSomething: ->
 
 buildListItem: (item, index) ->
      $li = $('<li/>')
      $li.on 'click', =>
        $li.addClass 'active'
        @doSomething()
        false
      $ul.append $li
  
 buildList: ->
   $ul = $('<ul/>')
   for item, index in @items 
      $ul.append @buildListItem item, index

Though this applies equally to JavaScript, I think that the very cleanness of CoffeeScript allows this sort of bug to creep in more easily. The lesson to take away — keep CoffeeScript methods small and objects well factored.

Wednesday, 30 May 2012

New Relic development mode

Further to my previous post on , the for applications gives you an awesome development mode and stats view for free.
Just add the gem to your application, install and restart, and visit the path /newrelic to see it.

Once again, Newrelic is awesome :)

Wednesday, 23 May 2012

Rice is Nice for Jasmine On Rails

Test first seems topical. Let me explain a little about how we do it here at Hedtek...

For , we run . To and JavaScript, we use . For on , we use to push Jasmine into the testing asset pipeline. Last week, we took a look around for a smooth way to integrate this continuously, and settled happily on .

When I see an open source project with a handful of documentation, a question springs to mind: can it really be this easy?

With jasminerice-runner, it is.

Just

#= require jasminerice_reporter

rake jasminerice:run

Good stuff, gaslight.

Thursday, 10 May 2012

First Time Heroku, Precompiling Assets

provides in the , and is well known as a host for apps. Last week, my first opportunity arrived to find out whether Heroku is as good as they say. I wasn't disappointed.

Following the documentation, everything progressed smoothly: signing up, installing Heroku Toolbelt, initial login, creating the cedar stack and the final push — except asset compilation. By default, Heroku continues even if asset compilation fails. So always read the output carefully:

$ git push heroku master
...
-----> Heroku receiving push
-----> Ruby/Rails app detected
-----> Installing dependencies using Bundler version 1.1.2
...
-----> Writing config/database.yml to read from DATABASE_URL
-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       rake aborted!
       could not connect to server: Connection refused
       Is the server running on host "127.0.0.1" and accepting
       TCP/IP connections on port 5432?
       
       Tasks: TOP => environment
       (See full trace by running task with --trace)
       Precompiling assets failed, enabling runtime asset compilation
       Injecting rails31_enable_runtime_asset_compilation
       Please see this article for troubleshooting help:
       http://devcenter.heroku.com/articles/rails31_heroku_cedar#troubleshooting
-----> Rails plugin injection
...

One simple way around an asset compilation issue is to:

  1. Compile locally
    $ bundle exec rake assets:precompile
    
  2. Commit assets to git
    $ git add -f public/assets/
    $ git commit -m "Precompile public assets"
    
  3. Push
    $ git push -f heroku master
    

And — after heroku run rake db:migrate — everything's great

-----> Writing config/database.yml to read from DATABASE_URL
-----> Preparing app for Rails asset pipeline
       Detected manifest.yml, assuming assets were compiled locally
-----> Rails plugin injection

or at least for me...

Friday, 4 May 2012

Newrelic

is awesome, simple and really easy server and application monitoring. Application monitoring is cool, and server monitoring cool and free.

How much more awesome do you need? Maybe a really easy setup to get the server monitoring on all your nodes?

Then just add your newrelic key to each node to be monitored under node[:newrelic][:license_key]

Monday, 30 April 2012

A "Hello, World" from File by Chef

First there was "Hello, World", Chef-style. Then again with attributes. Now to complete this short trilogy, we add some File interaction into the mix, deploying a text file in a step-by-step style...

Friday, 27 April 2012

A "Hello, World" with Attributes from Chef

Following on from the , this post continues to explore Chef from a development perspective. parameterise scripts. Let's introduce an attribute...

Wednesday, 25 April 2012

Google Web Fonts: Open Source Goodness

Intuitive and easy to use, altogether fontastic!

Meteor JS

Here at Hedtek we are all passionate about technology, always eager to try out something new: Like playing with a new web framework that has just been released, or even experimenting to see whether it's possible to have 4 different displays on a single Ubuntu machine (more about this in a later post).

Last week we decided to do a short on , the framework that has gained a lot of popularity over the last few weeks. Some results of this spike are reported here.

PhantomJS On Ubuntu

is a web stack with but . These qualities are useful more widely but today I'm interested in for a website in , and . Time to make PhantomJS 1.5.0 run on (11.10)...

PhantomJS avoids make, autoconf et al, preferring to roll their own build system. So it's best to grab a binary and follow the installation instructions. For x86 and x86_64 grab the appropriate dynamic build. For other platforms, pick a different tool...

And here's how it went...

Saturday, 21 April 2012

Performance at load of a Rails front end and DSpace implemented repository

We present a report that results from work commissioned by Jorum, an Open Educational Resources Repository built on DSpace.


We measured performance of a combination of a Ruby on Rails front end, a modified DSpace REST API, and an instance of DSpace. Measurements were performed over a University intranet segment using ApacheBench.


The report that contains a very comprehensive set of performance graphs for different kinds of accesses at different load levels. 


Download the report.

Friday, 20 April 2012

Compiled asset woes

3.1 introduced the , which is a great addition but can cause some unfortunate issues.
One that has recently been an issue for us is a cascade of behaviours that individually are all perfectly reasonable but, when combined, leave you with major headaches.

When you compile your assets with you get (as expected) your files, in compiled, minified form in the folder public/assets.

Files in public/assets are served in preference to anything produced by the Rails stack (they shadow your controllers). Perfect behaviour for caching, disabling certain routes, etc. and makes sure you are familiar with how things would act with a web server in front of Rails.

In development mode, Rails will serve all your javascript files separately, while precompiled only the manifest files will be present. So in development, you may have several (or even dozens) of files, while in production you only have one. Again, fantastic behaviour for caching, reducing requests and a whole host of other things.

In combination with precompiled assets though, it's disastrous. Your top level file (assets/application.js) in development is pretty much empty, but compiled contains all or almost all of your application's javascript. If the compiled version gets served in development then all your javascript is sent to the browser twice... and this is almost certainly going to break things.

If you're lucky and you have a light javascript application, the most you may notice is some effects not working correctly, maybe you'll investigate briefly on production and see it works fine, put it down as a development machine problem (or you'll solve the problem and never think about it again until it happens again).

On a heavy javascript application with a lot of javascript running in the browser, chances are your entire application will simply not work. If you aren't aware of the cascade of issues, this can take a long time to solve.

If you're running automated tests against everything (using tools like capybara-webkit or poltergeist) then the situation is slightly changed. In the test environment, Rails doesn't serve separate assets in a single file. But the file will still be served from public/assets in preference to the Rails stack, so your tests will run against the last version you precompiled. Again, this can be very confusing and even if you're aware of the previous behaviour it can take you a while to work out why tests that run fine on one machine (with no precompiled assets) don't work on another (where you precompiled assets last week for a demo and haven't cleaned them out).

Is there a solution? Yes, there's a very simple one. Simply configure Rails to serve your assets from a different location depending on environment.

Add the line to config/environments/development.rb file and a similar one to config/environments/test.rb
and the problem is now gone and you can compile assets on any machine without fear of causing issues if you forget to clean them up.

Thursday, 19 April 2012

HTML5 Local Storage

HTML5 brings developers lots of shiny new toys, varying in maturity and adoption. I'm happy to report that local storage — a stash of data persisted locally by the browser — now works wonderfully well on Mozilla Firefox 11 and Google Chrome 18.

Or at least as well as could be expected...

Some important consequences follow from the specification. In particular, local storage is sandboxed by domain — or more precisely [scheme, host, port] origin. Any script from the same origin shares the same local storage.

If you seek a secure local data stash for an authenticated user, local storage is not the API you're looking for...

Wednesday, 18 April 2012

Ruby On Gentoo with RVM

is my favoured but sometimes it takes time to learn to love its quirks. Last week, I found a tweak is needed to develop on using and . Here's how...

With a shiny new user and a shiny new .rvmrc after cd (into the directory) I see

==============================================================================
= NOTICE                                                                     
==============================================================================
= RVM has encountered a new or modified .rvmrc file in the current directory =
= This is a shell script and therefore may contain any shell commands.       =
=                                                                            =
= Examine the contents of this file carefully to be sure the contents are    =
= safe before trusting it! ( Choose v[iew] below to view the contents )      =
==============================================================================
Do you wish to trust this .rvmrc file? (/home/hedtek/space/.rvmrc)
y[es], n[o], v[iew], c[ancel]> y 

Trying to install bundler then fails with

$ gem install bundler
/home/hedtek/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/
  site_ruby/1.9.1/rubygems/custom_require.rb:36:
  in `require': cannot load such file -- auto_gem (LoadError)
 from /home/hedtek/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/
  site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'

Turns out that the Gentoo defaults don't play well with rails development. Easy to fix by an unset when starting a development session:

$ unset RUBYOPT

Once this has been done, all is good:

$ gem install bundler
Fetching: bundler-1.1.3.gem (100%)
Successfully installed bundler-1.1.3
1 gem installed
Installing ri documentation for bundler-1.1.3...
unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT 
to UTF-8 to US-ASCII for lib/bundler/vendor/thor/invocation.rb, skipping
Installing RDoc documentation for bundler-1.1.3...
unable to convert "\xC3" to UTF-8 in conversion 
from ASCII-8BIT to UTF-8 to US-ASCII 
for lib/bundler/vendor/thor/invocation.rb, skipping

Thanks to this post for setting me on the right road...

Monday, 16 April 2012

Brief Foray into HTML5 File APIs

Recently, using , I needed to . I couldn't find an easy way to do this within the library. Instead I used the to read the file in and simply send the file contents as part of the payload.

It turns out this is quite easy to do, although a bit verbose. You need to:
  1. Create a FileReader.
  2. Set an event handler for the onload event.
  3. Pass the file(s) you want to read to the appropriate reading method.
For a canned solution, this view for  will allow you to bind an attribute to the content of a file specified in a file field:

MyApp.Views.file = Ember.View.extend                             
  tagName: 'input'                                     
  attributeBindings: ['type', 'id']                     
  type: 'file' 
                           
  change: (e)->       
    view = this                                
    reader = new FileReader()                                         
    reader.onload = (e)->             
      view.set('file', e.target.result)                    
    reader.readAsText(e.target.files[0]) 

This can then be invoked in a template as follows:

{{view MyApp.Views.file fileBinding="SomeModel.attribute" }}

I expect this approach to be unsuitable for extremely large files as it will read the entire file into memory and transmit it as part of the payload rather than as a file upload, for some value of extremely large...

Wednesday, 28 March 2012

A "Hello World" from Chef

If - like me - you're a developer beginning to play around with , perhaps you've found that many quick start tutorials seem more Ops than Dev. Read on for a mixed with some opinions about development on Chef. Thanks toJonathan Otto and morethanseven for blazing this trail.

An efficient feedback loop matters to me, and isolation between projects. Installing a server and setting up a workstation for each project sounds too slow.

So use [1]
$ chef-solo --version
Chef: 0.10.8

in a workspace for project hello

$ mkdir --parents chef-workspace/hello
$ cd chef-workspace/hello

under version control

$ git init 

Isolate the new project from its environment by grouping the configuration files together

$ mkdir config

and separate them from the code

$ mkdir cookbooks

A minimal configuration to wire in this project layout, setting the conventional cookbook_path, may be written in

cookbook_path File.expand_path(File.join(File.dirname(__FILE__), '..', "cookbooks"))

Save this into config/chef-solo-config.rb, a reasonable naming convention for the configuration file passed to chef-solo. Attributes declaring the exercise are passed through a second file, encoded in JSON. A minimal Hello, World exercise, running just the default recipe from a cookbook called hello_world, is

{"run_list": ["recipe[hello_world]"]}

Save this config/from-hello_world-run-default.json, a conventional name for an exercise that runs the default recipe from the hello_world cookbook. Create a directory for this cookbook

$ mkdir cookbooks/hello_world

with space ready for a recipe

$ mkdir cookbooks/hello_world/recipes

Chef supports logging out-of-the-box, and so an easy way to say hello is

log("Hello, World") { level :info }

Save this into cookbooks/example/recipes/default.rb, and Chef will run this when the no recipe name is given (for this cookbook).


Ready to cook[2]

$ sudo chef-solo --config config/chef-solo-config.rb 
   --json-attributes config/from-hello_world-run-default.json
[...] INFO: Starting Chef Solo Run
[...] INFO: Replacing the run_list with ["recipe[hello_world]"] from JSON
[...] INFO: Hello, World
[...] INFO: Chef Run complete in 0.885143 seconds

Hello, World — served up by Chef.


Simple.

A few more sophisticated examples are queued in the draft pipeline, so check back later for more on Chef - or subscribe to the feed.


[1] Chef moves fast: install the lates
[2] unless you forget to sudo
$ chef-solo --config config/chef-solo-config.rb 
     --json-attributes config/from-hello_world-run-default.json

[...] FATAL: Failed to read the private key /etc/chef/client.pem: 
#<Errno::EACCES: Permission denied - /etc/chef/client.pem>, 
/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:59:in 
 `read'/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:59:in 
 `load_signing_key'/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:33:in 
 `initialize'/usr/lib/ruby/1.8/chef/rest.rb:40:in 
 `new'/usr/lib/ruby/1.8/chef/rest.rb:40:in 
 `initialize'/usr/lib/ruby/1.8/chef/client.rb:54:in 
  `new'/usr/lib/ruby/1.8/chef/client.rb:54:in 
 `initialize'/usr/lib/ruby/1.8/chef/application/solo.rb:180:in 
 `new'/usr/lib/ruby/1.8/chef/application/solo.rb:180:in 
 `setup_application'/usr/lib/ruby/1.8/chef/application.rb:61:in 
  `run'/usr/bin/chef-solo:24
/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:62:in 
 `load_signing_key': I cannot read /etc/chef/client.pem, 
   which you told me to use to sign requests! 
    (Chef::Exceptions::PrivateKeyMissing)
 from /usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:33:in `initialize'
 from /usr/lib/ruby/1.8/chef/rest.rb:40:in `new'
 from /usr/lib/ruby/1.8/chef/rest.rb:40:in `initialize'
 from /usr/lib/ruby/1.8/chef/client.rb:54:in `new'
 from /usr/lib/ruby/1.8/chef/client.rb:54:in `initialize'
 from /usr/lib/ruby/1.8/chef/application/solo.rb:180:in `new'
 from /usr/lib/ruby/1.8/chef/application/solo.rb:180:in `setup_application'
 from /usr/lib/ruby/1.8/chef/application.rb:61:in `run'
 from /usr/bin/chef-solo:24

Tuesday, 27 March 2012

Starting with ember.js and Rails

For a new project, I've been investigating frameworks for a richer front-end. I settled on because it provides a reasonably understandable object model and it has features like templating baked in, rather than needing to be added manually like in many other javascript frameworks. Ember.js also has the ability to define bindings that automatically update your view by manipulating the bound javascript objects.

After some investigation, I found some useful posts on setting up an Ember.js application, one rails specific and one that introduces a layout system and a routing system. This prompted some experimentation to set up a front end that is manageable, suits the project and allows us to quickly add to the front-end.

The end result is a set of generators and asset-pipeline suitable gems for quickly getting started with Ember.js. The first thing to note is that the generators are opinionated - they assume you are using and within the Rails asset pipeline. To help with this, the bootstrap generator adds the appropriate gems to your Gemfile.

More details can be found in the git repositories for the 4 gems created for the project: