Announcing Heroku for Logo... powered by Heroku

Since launching Ruby support in 2007, we’ve been constantly expanding the platform to accommodate more application types and to make the platform more accessible to a broader audience of developers.

We are very pleased today to announce full support for applications written in the Logo programming language.

Going back to our roots with an in-browser editor, we believe that interactive programming and getting started quickly lend well to learning. Ruby is an excellent language for learning (check out Hackety Hack), and Logo is even better.

Logo is a fully-featured and beautifully designed functional Lisp-style programming language. It shares many properties with (and is an ancestor of, via Smalltalk) Ruby, including being an interpreted language with dynamic typing and excellent set manipulation – including filter, map, reduce, and other iterators similar to Ruby’s excellent Enumerable methods.

Available Immediately

Experimental Logo support is available immediately and can be used by simply pushing an application to Heroku that contains a file with the .lgo suffix.

Check out our example apps cranes.heroku.com and logo-blank.heroku.com. Then give it a try yourself:

$ echo "fd 100 rt 90 fd 100" > cranes.lgo
$ git init && git add . && git commit -m init
$ heroku create cranes
Created http://cranes.heroku.com/ | git@heroku.com:cranes.git

$ git push heroku master
-----> Heroku receiving push
-----> Logo app detected
-----> Embedding Logo runtime... done
       Compiled slug size is 20K
-----> Launching... done
       http://cranes.heroku.com deployed to Heroku

More details available in the Dev Center.

Submit Cool Apps for Prizes

If you build an awesome Logo app this weekend, tweet it @heroku. On Monday we’ll pick the 10 coolest Logo apps to showcase, and the winners will receive Heroku care packages with t-shirts, stickers, and platform credits.

Attribution

Heroku’s Logo support is based on the excellent Javascript-based Logo Interpreter by Joshua Bell.

Background Jobs with DJ on Heroku

Our goal for the Heroku platform has been to create a totally smooth and seamless experience for getting your Ruby web application online. Web apps revolve around one or more dynamic web processes: what Rubyists often call a mongrel, and what we call a dyno. When it comes to dynos, we think we’ve really nailed it, and nothing makes that more tangible than the ease of scaling your app with the dyno slider.

But most serious web apps have a second aspect: one that gets less attention, but one that is often just as important as the web process. Like the dark side of the moon, this second half of your application is not directly visible to users, but without it the app would not be whole. This aspect of the application is often referred to as background jobs. The processes which handle background jobs are called workers.

A worker is used for any heavy lifting your app needs to do. Some examples include: sending email, accessing a remote API (like posting something to Twitter), fetching posts from an RSS feed, converting an image thumbnail, or rendering a PDF. Anything that will take more than 100ms should go in a worker process, not your web process.

Ad-hoc Background Jobs

There are many ways to create worker processes that run asynchronously from your web requests. Examples include forking a web process, or running a cron job every minute to check for work. Those ad-hoc techniques work ok in some situations, but they not highly maintainable or scalable. At Heroku, we don’t want to do something unless we can do it right. We want our workers to be as smooth, powerful, scalable, and easy to use as our dynos.

Background Jobs Done Right

Worker processes on Heroku run completely independently of your dynos. They can be scaled out horizontally across our grid of instances to any size, independent of the number of dynos you’re running. (Some apps need more concurrency for the web front, some for the background workers – scaling the two should be orthogonal.)

One way to describe a mongrel or dyno is as a share-nothing process that consumes web requests. Likewise, a worker can be described as a share-nothing process that consumes jobs from a work queue.

Work Queues

Work queues are currently an area of academic debate among thought leaders in the Ruby community. Work queues consist of two parts: a queueing system and a message bus. The message bus may be an implementation of a messaging standard, or a custom protocol.

Some examples of queueing systems include: Delayed::Job, Workling, BJ, and Starling.

Some examples of message buses include: RabbitMQ (implementing the AMQP protocol), Beanstalkd, Amazon SQS, and Kestrel.

These are some great tools, many of which are in production use by major Ruby sites. For example, Twitter uses Kestrel, while Scribd uses loops and ActiveMQ. But when the largest Rails sites in the world don’t have a consensus on the best tool for the job, what should the rest of us be using?

Luckily, there’s an excellent solution for medium-sized apps that has been quietly gaining momentum in the Rails world. That solution is Delayed::Job.

Delayed Job

DJ is an easy-as-pie plugin for Rails written by Tobias L├╝tke. (It can be used with Sinatra, too). It uses the database as a message bus instead of an external daemon. Using the database as the message bus isn’t as high-speed or featureful as a dedicated daemon like RabbitMQ, but it’s easier to set up, and more than enough for most sites – including Github.

John Nunemaker has an excellent tutorial on DJ, and I’ve previously illustrated the steps for building a queue-backed feed reader. So there’s plenty of material to get you going with this plugin.

DJ on Heroku

We’re pleased to announce the first iteration of support for background jobs on Heroku, in the form of DJ support. This has been in heavy beta use by a large group of Heroku beta users (thanks guys!) for the last four months, so we feel very confident that this is a solid solution, ready for real production use today.

Our first publicly-priced offering is a single DJ worker, at $15/mo. You can activate it for your app through the usual add-on interface:

$ heroku addons:add dj
Adding dj to myapp...done.

Follow the instructions for installing the DJ plugin and creating the delayed_jobs table, and you’ll be up and running in minutes. (That’s the smooth, seamless experience you’ve come to expect from Heroku.)

More to Come

If you need something beyond the publicly-priced single worker DJ, contact us. Multi-worker setup, and a more powerful message bus (RabbitMQ) are things we already have in late alpha / early beta status. If you’ve got an app that you think can put these technologies to the test, we’d love to hear from you.

Add-on: Wildcard Domains

Since we returned from a fun and successful Railsconf in Vegas, we have been in full swing completing the rollout of our paid services. The response has been enormous so far, and paid services are now available to all users.

If you’ve checked out the pricing page, you’ve undoubtedly noticed our line-up of a la carte add-ons. We’re really excited about add-ons becoming a key part of our platform, allowing us to seamlessly deliver popular application services and components with the built-in scalability and ease of use you’ve come to expect from Heroku.

We’ve had a solid first batch of add-ons in beta for a while, and today we’re happy to announce the first graduate: Wildcard Domains, which allows your app to respond on *.yourdomain.com. Since we started supporting custom domains on Heroku this has been high on the list of requested features, and now it’s here! To add it to your app for $5/month, simply go to your app’s Resources page and select turn it on. Enjoy!

Config Vars for Deploy-Specific Settings

Say you’re working on a Rails app, and you want to publish your code on Github. Most apps have some deploy-specific private config values – for example, if you’re using the S3 storage backend for Paperclip, and your S3 keys are saved in config/amazon_keys.yml. You certainly don’t want to push those up to Github – what to do?

You could maintain a separate deploy branch, and commit your deploy config only to that. You can then work on the main branch, and rebase the deploy branch whenever you go for a deploy. That’s a bit of extra work you could do without, though – and you know sooner or later, you’re going to accidentally push the wrong branch to Github, putting your S3 keys up for the whole world to see. Oops.

Wouldn’t it be nice avoid all this headache by storing the data specific to your app’s deploy in a separate configuration registry?

Now you can. Check it out:

$ heroku config:add S3_BUCKET=mybucket S3_KEY=8N029N81 S3_SECRET=9s83109d3+583493190
Adding config vars:
  S3_BUCKET => mybucket
  S3_KEY    => 8N029N81
  S3_SECRET => 9s83109d3+583493190
Restarting app...done.

Your config vars are now accessible in the environment variables for your deployed app. Configure Paperclip like this:

has_attached_file :photo,
  :storage => :s3,
  :s3_credentials => {
    :access_key_id => ENV['S3_KEY'],
    :secret_access_key => ENV['S3_SECRET']
  },
  :bucket => ENV['S3_BUCKET'],
  :path => ":attachment/:id"

Set up like this, your public code and your deployed code can be exactly the same. Push to Github all day long with no fear of leaking your private credentials. Clean and neat, no fuss, no muss.

This also means you can set different config vars for different deployed versions of the app. For example, if you run a staging deploy of your code on Heroku, you can set it to use a different S3 bucket – maybe “myapp_assets” for production and “myapp_staging_assets” for staging.

What about running locally, deploying to a traditional host? Since these are just environment variables, you can set them just as you normally would – in your .bashrc (export S3_BUCKET=mybucket), or on the command line when you run the server.

Or, you can check for the presence of the vars, and use defaults when they don’t exist. In the case of Paperclip, you might do:

has_attached_file :photo,
  :storage => ENV['S3_BUCKET'] ? :s3 : :filesystem,
  ...

Now when you run locally, it’ll use the filesystem store; but running on a deployed app with the S3_BUCKET var set, it’ll automatically go to the right place.

There are many other uses for config vars. For example, you can set RACK_ENV to something other than the default of ‘production’. (RAILS_ENV and MERB_ENV will automatically mirror RACK_ENV on Heroku.) So if you prefer the traditional approach of storing different keys for different environments (development/staging/production) in various config/something.yml files, set your RACK_ENV as appropriate for your staging and production deployed apps on Heroku.

Read the full documentation. Note that you’ll need to grab the 0.7 Heroku client gem (it’s in Rubyforge now, so `gem install heroku` will do the trick) to use this feature.

Heroku API Update

The Heroku API gets a major update today; you can now view and manage all of your application’s settings straight from the command line. New in this version:

  • Manage sharing (add/remove/list collaborators)
  • Manage multiple ssh keys for your user (add/remove/list keys)
  • Update settings (public true/false, mode production/development)
  • Rename an app
  • Run rake tasks remotely

A taste of the new command-line goodness:

adam@kvasir:~$ heroku create gagetron
Created http://gagetron.heroku.com/ | git@heroku.com:gagetron.git
adam@kvasir:~$ heroku info gagetron
=== gagetron
Web URL:        http://gagetron.heroku.com/
Git Repo:       git@heroku.com:gagetron.git
Mode:           development
Public:         false
Collaborators:  adam@example.com (edit)
adam@kvasir:~$ heroku sharing gagetron --add joe@example.com
joe@example.com added as a view-only collaborator on gagetron.
adam@kvasir:~$ heroku rake gagetron routes
(in /mnt/home/userapps/27934)
  /:controller/:action/:id         
  /:controller/:action/:id.:format 

There’s a new screencast which shows managing sharing from the command line. We’ve also updated the screencasts which show how to use the API and Git to edit locally, then deploy to Heroku.

Grab the new gem from Rubyforge with gem install heroku, read the docs, or browse the source.

Browse the blog archives or subscribe to the full-text feed.