Tuesday Tricks - JavaScript Timer Differentials

Timers in JavaScript can be either very simple or become very difficult. In most cases, timers are very simple, such as polling a resource to update content on a SPA (Single-Page Application). In this case, you don't really care when you get your updates from the server, as long as you get them within, say, 1 second of when you expect to receive a response.

But how about when you need a timer to execute at an exact moment in time (ie: a game)? Well, this isn't possible. The best JavaScript can do is guarantee that your function will be run. It doesn't guarantee that it will be run at a specific time. This is because there could be other processes running when you request your timeout, using setTimeout.

When you call setTimeout with a 5000 millisecond delay, it may run in exactly 5000 milliseconds and it may not, depending on what is being processed and what is in the queue. If your setTimeout call gets placed in the queue for 50 milliseconds, your function will be run at 5050 milliseconds. The delay is unpredictable. It's a fact of cyber-life.

Timer Differentials

You can't tell how long your setTimeout call will remain in the queue (and offset your timing), but you can tell how long it remained in the queue after it has been executed. Be careful, it's only supported by Firefox.

setTimeout(function(diff) {
  if( diff > 0 ) {
// function was in the queue
} else if( diff < 0 ) {
// function was called early
} else {
//function was called on time
}
}, 5000);

This Tuesday's Trick

You probably never develop applications that only run in Firefox, but it's helpful to know that you can make your timing more accurate in the instance the user's browser is Firefox. setTimeout differential will help you do just that.

Posted by Mike Pack on 05/17/2011 at 12:23PM

Tags: tuesday tricks, javascript, timers


FreshBooks on Rack...on Heroku - Part Three

In Part One of this series, we constructed a "hello world" Rack app. In Part Two of this series, we brought our app to life with the ruby-freshbooks library. In this part, we'll quickly finish out by deploying our app to Heroku.

For the entire source code, head to https://github.com/mikepack/freshbooks_on_rack.

Getting the app on Heroku

The next step is getting your app on Heroku. You'll need a Heroku account first, obviously, and you'll need to configure your Heroku account so that your SSH key is recognized.

First, create your git repository and commit your files:

cd fb_on_rack_dir
git init
git add .
git commit -m 'Here is the app!'

Create your Heroku app:

heroku create your-fb-heroku-app

Push your changes to Heroku:

git push heroku master

Check it out! Open your browser, head to http://your-fb-heroku-app.heroku.com and you should see your running Rack app iterating over all your projects.

Rack HTTP Basic Authentication

Most likely, with all those valuable numbers, you don't want your app exposed to the world. The most simple way to remedy this is to add HTTP Basic Auth to your app. Rack makes this dead easy.

Change your config.ru file to look like the following:

config.ru

require 'rack'
require 'fb_on_rack'

use Rack::Auth::Basic, "FreshBooks on Rack" do |user, pass|
  user == 'me' and pass == 'secret'
end

run FBOnRack.new

This will present you with the oh-so-familiar HTTP Basic Auth prompt. We've hardcoded the username and password to be me and secret, respectively. You're now protected from all those internet wanderers.

A quick note about simplicity

While I greatly appreciate elucid's work on the library, ruby-freshbooks isn't perfect. During the creation of this app, I got some unexpected values as I was iterating through result sets. For instance, one iteration would provide me with a hash and the next an array. Here's an error indicative of the inconsistent result set:

TypeError at /
cant convert String into Integer

Ruby /mnt/hgfs/share/freskbooks_on_rack/fb_on_rack.rb: in [], line 25 Web GET localhost/

If you see this error, check your result set and handle it appropriately.

In Ruby 1.9.2, I would receive the following error as I started the Rack app with rackup:

ruby-1.9.2-p136/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': no such file to load -- fb_on_rack (LoadError)

This error is due to changes in Ruby 1.9 require's path expectation. To fix this...

config.ru

require 'fb_on_rack'

...should look like...

config.ru

require './fb_on_rack'

I wouldn't, by a stretch, call this a production-ready app. In lieu of handling all error and usecase situations, I kept it simple. My main goal is to show you the basics of working with the ruby-freshbooks gem and the potential it holds for aggregating important data.

Happy Freshbooking!

Posted by Mike Pack on 05/12/2011 at 05:26PM

Tags: freshbooks, rack, heroku, api


Tuesday Tricks - Splatting

In Ruby, the * (asterisk) token is often referred to as the "splat operator". It's purpose is to turn a group of arguments into an array. This can be useful if you want to accept an enumeration to your method but don't care how it's formed. For example:

def note_tasks(*tasks)
  puts "[ ] #{tasks.join(' and ')}"
end

note_tasks('mow the lawn') #=> [ ] mow the lawn
note_tasks('take out the trash', 'walk the dog') #=> [ ] mow the lawn and walk the dog
note_tasks(['feed yourself', 'get some sleep']) #=> [ ] feed yourself and get some sleep

Splatting in Ruby 1.9

In Ruby 1.8 you were constricted to using the splat operator on the last argument in a method signature. In Ruby 1.9, you can splat anywhere.

def note_task(name, *options, stream)
  $stdout = stream
  puts "#{options.first.to_s}#{name}#{options.last.to_s}"
end

note_task('mow the lawn', '[ ] ', 'ignored', '!!', $stdout)
#=> [ ] mow the lawn!!

The above method shouldn't normally be defined in such a way. It would make much more sense to define it with stream as the second argument and allow options to be a trailing hash.

def note_task(name, stream, options = {})
  $stdout = stream
  puts "#{options[:before].to_s}Make sure you #{name}#{options[:after].to_s}"
end

note_task('mow the lawn', File.new('/dev/null', 'w'), :before => '[ ] ',
:ignore => 'this',
:after => '!!')
#=> [ ] mow the lawn!! (to /dev/null)
note_task('mow the lawn', File.new('/dev/null', 'w'))
#=> mow the lawn (to /dev/null)

Ruby will automatically convert the trailing parameters into a hash. Thanks Ruby.

This Tuesday's Trick

Splatting is fun and useful, but careful, it can sometimes decrease the integrity of your method signature. Mainly use them when you have a trailing enumerable set that can be passed as a list of arguments.

Posted by Mike Pack on 05/10/2011 at 03:55PM

Tags: tuesday tricks, splat, ruby