Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

85 lines (55 sloc) 9.253 kb

Introduction

This tutorial will show you how to delegate lengthy and/or resource-consuming operations to IronWorker. Let's take a look at a simple application whose only purpose is to check if a supplied number is prime or not. There are three important pieces: the function, which checks if a number is prime, the controller, which runs the function to process a user's input, and the script, which sends the entered number to the controller and presents the results to the user.

Start the application and check that it works as expected. Try some big prime numbers like 2932031007403 or 768614336404564651 (the last one might take several minutes to check and will make heavy use of your CPU). Please note that various checks were omitted for simplicity (e.g. we assume all inputs are correct).

So why you might need IronWorker in this simple application? Imagine that it's used by students in class, so load isn't uniform, you have only few hours per day where you need lots of CPU power. Launching lots of servers before class and shutting them down afterwards will be very inconvinient and IronWorker is here to help.

Preparing The IronWorker Environment

To use IronWorker you'll need to create an iron.io account. After completing registration, you'll end up at the dashboard, where you can manage your projects. Create a new project there named 'TutorialPrimes'. Note that it's generally good practice to have separate Iron.io projects for each environment (production and development).

Your Rails application will need your Iron.io credentials to create workers and communicate with them, so download the iron.json file from the 'Get Started' tab and put it into root directory of your application. You'll also need the IronWorker Ruby library, so add gem iron_worker_ng to your Gemfile and run bundle.

Finally, create an IronWorker client object in a custom initializer. Don't forget to restart your application. At the end you should have something like this.

Creating The Worker

Workers are standalone pieces of code that will be executed on Iron.io's servers. Move the code from PrimesController#check action into a worker. You'll also need .worker file, which describes what will be uploaded to and executed on the server (in our case, we need prime.rb with prime? function). Note that all of the worker's output will be logged, and we'll use it to retrive results from worker. Later in this tutorial we will use IronCache for this.

If your worker is set up correctly, it should look like this.

Uploading And Testing Worker

Before you can start creating tasks, you need to upload your worker to the Iron.io cloud. Simply run iron_worker upload workers/primes_check from the root of your application.

iced@iced tutorial_primes % iron_worker upload workers/primes_check
------> Creating client
        Project 'TutorialPrimes' with id='5047e9a40e59fb1b73001244'
------> Creating code package
        Found workerfile with path='workers/primes_check.worker'
        Detected exec with path='primes_check.rb' and args='{}'
        Merging file with path='../lib/prime.rb' and dest=''
        Code package name is 'primes_check'
------> Uploading code package 'primes_check'
        Code package uploaded with id='5057860b29a33a5765090302' and revision='1'
        Check 'https://hud.iron.io/tq/projects/5047e9a40e59fb1b73001244/code/5057860b29a33a5765090302' for more info

Next, queue up a task. Note that the JSON passed as the payload will be decoded on worker execution and passed into the params variable automatically, just like in the Rails controller action.

iced@iced tutorial_primes % iron_worker queue primes_check --payload "{\"number\": \"13\"}"
------> Creating client
        Project 'TutorialPrimes' with id='5047e9a40e59fb1b73001244'
------> Queueing task
        Code package 'primes_check' queued with id='5057864d29a33a576509030e'
        Check 'https://hud.iron.io/tq/projects/5047e9a40e59fb1b73001244/jobs/5057864d29a33a576509030e' for more info

Finally, check the task log to ensure the worker did the job.

iced@iced tutorial_primes % iron_worker log 5057864d29a33a576509030e
------> Creating client
        Project 'TutorialPrimes' with id='5047e9a40e59fb1b73001244'
------> Getting log for task with id='5057864d29a33a576509030e'
13: is prime

Important note: while it's perfectly safe to share IDs (project_id, task_id, etc.), it's very important that you keep your token secret. If your token is compromised, make sure to delete it and create new one.

Putting It Together

Finally, make the PrimesController#check action to queue up a worker task with the passed number as the parameter and then return the task_id back to the client. We'll also need a new PrimesController#check_result action, which will accept a task_id as a parameter and return 'checking' if the worker is still running, or whether the number is prime if the worker has finished running.

Our script can then poll for result using Ben Alman's jQuery doTimeout plugin. That's it!

Addding IronCache To Mix

Using logs for communication between your app and workers isn't really convinient and you might notice that results aren't cached, so application will waste time checking same number again and again. So, let's cache them using IronCache.

We will need client library in Gemfile and custom initializer. Notice that IronCache will use the same credentials as IronWorker, so no extra configuration needed. Don't forget to run bundle and restart your application.

Our worker will need IronCache initializer, iron.io configuration file (which will go to initializers directory) and IronCache client library. Also, let's make it to put result into cache rather than just logging it. Now reupload worker with iron_worker upload workers/primes_check.

PrimesController#check will now queue worker only if requested number wasn't computed before (or isn't computing now) and PrimesController#check_result will just look in the cache for it. Small adjustments to script are needed as well.

Check that application will show check result instantly even for big primes if they were computed before.

Refactoring

You might notice that PrimesController#check_result actually does the same job as PrimesController#check so we can get rid of it. This will also allow us to simplify the script. Enjoy!

Jump to Line
Something went wrong with that request. Please try again.