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 authorization (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 authorized 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.