Skip to content

Instantly share code, notes, and snippets.

@lstoll
Created March 26, 2012 01:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lstoll/2202255 to your computer and use it in GitHub Desktop.
Save lstoll/2202255 to your computer and use it in GitHub Desktop.
Scheudling jobs on heroku with the play framework.

Jobs with the Play! Framework and Heroku

First thing, create a job that runs your task. Don't set a timer or anything on it, we will trigger it manually.

You will need to add two things to your app. First is an endpoint that uses authorisation (for your security) to trigger the job in the background. Something like this will do it:

public class JobEndpoint extends Controller{ 
    public static void runTheJob(){ 
        if( "jobuser".equals(request.username) && "jobpass".equals(request.password) ){ 
            new WhateverYourJobClassIs().now(); 
            renderText("Job Running"); 
        } 
        else { 
            renderText("Unauthorized"); 
        } 
    } 
}

This controller will check the basic auth headers to make sure the caller is authorised to start the job. If they are, it will create a new instance of your Job, and call the 'now' method to invoke it immediately. This will return a future, but as we are just triggering the job we can ignore it, and return the HTTP request. This prevents hitting the 30s timeout.

You can then create a shell script in your application to call wherever you set the route to this function.

bin/jobtrigger.sh:

#!/bin/bash 
curl -u jobuser:jobpass http://yourapp.herokuapp.com/path/to/jobendpoint

Make sure you mark this file as executable before committing it: chmod +x bin/jobtrigger.sh

Once you've done this, you can test it with

$ heroku run bin/jobtrigger.sh

to verify that it runs the job. Once you're happy, you can just point the scheduler to 'bin/jobtrigger.sh' to trigger the job. Because this will 'fire and forget' the job, you will need to keep track of the job results in your application - like if you're using the play scheduler.

@paulwehner
Copy link

Maybe I'm missing something, but this would only work with "web" dynos right? I thought "worker" dynos, which are the ones you would want to use for a Job, since they won't idle out, don't take incoming HTTP requests.

@lstoll
Copy link
Author

lstoll commented May 3, 2012

You are correct - you have 15 minutes before idling from inactivity, so if you job gets close to that this method won't work. For most simpler jobs though it is completely acceptable.

You can run a 'worker' instance of play, running the built in job framework for your timing and jobs as well - this was more for simple timed jobs without the effort. I can add information on that to this doc if you like?

@rjstanford
Copy link

Belated, but this page coms up high on Google results - you can also set the scheduler to run 'curl -u jobuser:jobpass http://yourapp.herokuapp.com/path/to/jobendpoint' and not worry about adding the script in code. Both approaches have their pros and cons.

@sbuljat
Copy link

sbuljat commented Mar 26, 2015

I had trouble using shell script, heroku kept throwing error "No such file or directory". I've tried putting script in bin and dist folders but without luck. Advice from @rjstanford really helped and it's much easier... thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment