ACK Foundry
Last updated January 29, 2018
The ACK Foundry add-on is currently in beta.
Table of Contents
ACK Foundry is an add-on that provides Faktory as a service. Faktory is a high-performance job management server that handles queueing, retrying, and scheduling of asynchronous background jobs from almost any web framework.
ACK Foundry provides access to the Faktory web UI interface (accessible from any web browser), as well the core Faktory API. Client libraries for a variety of languages are available here.
Provisioning the add-on
ACK Foundry can be attached to a Heroku application via the CLI:
A list of all plans available can be found here.
$ heroku addons:create ackfoundry
-----> Adding ackfoundry to sharp-mountain-4005... done, v18 (free)
After you provision ACK Foundry, the ACK_FOUNDRY_API_URL
config var is available in your app’s configuration. It contains the canonical root API URL for your new Faktory instance.
When using most Faktory client libraries, you can set the FAKTORY_PROVIDER
environment variable to indicate which other environment variable contains the base API URL for your Faktory instance. Set the value of FAKTORY_PROVIDER
to ACK_FOUNDRY_API_URL
to easily resolve API endpoints.
ACK Foundry also sets the ACK_FOUNDRY_WEB_URL
config var, which contains the URL for your Faktory web UI.
You can confirm the values of these config vars with the heroku config:get
command:
$ heroku config:get ACK_FOUNDRY_API_URL
tcp://:pass@shared.ackfoundry.com:port
After you install ACK Foundry, your application should be configured to fully integrate with the add-on.
Credentials are included as part of ACK_FOUNDRY_API_URL
and
ACK_FOUNDRY_WEB_URL
and so they shouldn’t be stored insecurely.
Local setup
It’s best to run Faktory locally to ensure parity between environments. You can install it directly on either Linux or macOS, and it is also distributed as a docker image for easy setup in development.
Setup using Docker
Full instructions on installing Faktory on any supported environment can be found in the Faktory wiki. However, if you have access to Docker, you can run Faktory easily with a single command:
$ docker run --rm -it -p 127.0.0.1:7419:7419 -p 127.0.0.1:7420:7420 contribsys/faktory:latest -b 0.0.0.0:7419
Once the container starts, you’ll have access to the Faktory server at tcp://localhost:7419
and the web interface at http://localhost:7420
.
Using with Rails
Ruby on Rails applications need to use the Ruby client for Faktory.
Install the client
To use the client, add the following entry to your Gemfile
:
gem 'faktory_worker_ruby'
Then, update application dependencies with bundler:
$ bundle install
Build a job
The Faktory client allows you to create workers that are responsible for executing the long-running code of your business logic. The faktory_worker_ruby
library doesn’t currently have an ActiveJob integration, so you need to include the Faktory::Job
module in your workers. If you want to prevent duplication and repetitive typing, you can include it in the ApplicationJob
class generated by Rails:
# app/jobs/application_job.rb
class ApplicationJob
include Faktory::Job
end
Now to create a new worker, just inherit from this main job:
class MyJob < ApplicationJob
def perform(...)
# Something that takes a while...
end
end
Queue a job
Jobs can be queued for execution by calling perform_async
on the job class:
MyJob.perform_async(...)
Run your workers
The last step to running Faktory locally is to run the process that will actually execute your job by adding the following to your Procfile
:
worker: bundle exec faktory-worker
Using with Go
Go applications need to use the Go client for Faktory.
Install the client
Run the following command to install the Go client:
$ go get -u github.com/contribsys/faktory_worker_go
Build a job
To implement a worker in Go, simply define a func with your long-running logic:
import (
worker "github.com/contribsys/faktory_worker_go"
)
func myFunc(ctx worker.Context, args ...interface{}) error {
fmt.Println("Working on job", ctx.Jid())
return nil
}
Queue a job
Jobs can be queued in the Go client like this:
import (
faktory github.com/contribsys/faktory/client
)
client, err := faktory.Open()
job := faktory.NewJob("MyJob")
err = client.Push(job)
Run your workers
To run your workers in the Go client, you need to set up the worker manager:
func main() {
mgr := worker.NewManager()
// register your job types and the associated function
mgr.Register("MyJob", myFunc)
// Set concurrency and queue options
mgr.Concurrency = 20
mgr.Queues = []string("critical", "default", "bulk")
// Start processing jobs
mgr.Run()
}
Using with Node.js
Node.js applications need to use the Node client for Faktory.
Install the client
Install the Node client with npm like so:
$ npm install faktory-worker
Build a job
A job function can be a sync or async function. Simply return a promise or use await
in your async function to perform async tasks during your job. If you return early or don’t await
properly, the job will be ACKed when the function returns.
const faktory = require('faktory-worker');
faktory.register('MyJob', async (id, size) => {
await somethingAsync(id);
}
Queue a job
const faktory = require('faktory-worker');
const client = await faktory.connect();
client.push({
queue: 'default',
jobtype: 'MyJob',
args: []
});
Run your workers
To begin polling for jobs:
faktory.work();
Using with PHP
PHP applications need to use the PHP client for Faktory.
Install the client
Install the PHP client via Composer like so:
$ composer require basekit/faktory_worker_php
Build a job
A job is just a function registered with your Faktory worker:
function ($job) {
echo "Printing from a job\n";
var_dump($job);
}
Queue a job
$client = new FaktoryClient($faktoryHost, $faktoryPort);
$job = new FaktoryJob($id, $type, $args);
$client->push($job)
Run your workers
Jobs must be registered with the worker and queue configurations must be set before running the worker:
$client = new FaktoryClient($faktoryHost, $faktoryPort);
$worker = new FaktoryWorker($client);
$worker->register('somejob', function ($job) {
echo "You got the job buddy!\n";
var_dump($job);
});
$worker->setQueues(['critical', 'default', 'bulk']);
$worker->run();
Using with Python
Python applications need to use the Python client for Faktory.
Install the client
The Faktory Python client is distributed via pip:
$ pip install faktory
Build a job
Jobs in the Python client are just functions registered to the worker. To build a job, create a function containing all your long-running logic:
def my_job():
return 0
Queue a job
import faktory
with faktory.connection() as client:
client.queue('myJob', args=(1,2))
Run your workers
As with the other clients, any job functions must be registered along with any worker configuration prior to running the worker:
from faktory import Worker
w = Worker(queues=['default'], concurrency=1)
w.register('myJob', my_job)
w.run()
Migrating between plans
Application owners should carefully manage the migration timing to ensure proper application function during the migration process.
warning
ACK Foundry is currently in alpha testing so there is only one plan, test
. Instructions for upgrading will be added here when there are more plans available.
Use the heroku addons:upgrade
command to migrate to a new plan.
$ heroku addons:upgrade ackfoundry:newplan
-----> Upgrading ackfoundry:newplan to sharp-mountain-4005... done, v18 ($49/mo)
Your plan has been updated to: ackfoundry:newplan
Removing the add-on
You can remove ACK Foundry via the CLI:
This will destroy all associated data and cannot be undone!
$ heroku addons:destroy ackfoundry
-----> Removing ackfoundry from sharp-mountain-4005... done, v20 (free)
Support
All ACK Foundry support and runtime issues should be submitted via one of the Heroku Support channels. Any non-support related issues or product feedback is welcome at admin@ackfoundry.com.