Procrastinate Integration
Since v2.1.0
The Procrastinate integration lets you automatically create and update Task Badger tasks from
Procrastinate jobs. It tracks the full
lifecycle of a job — pending when the job is deferred, processing when the worker starts it, and
success or error when it finishes.
Install the optional extra to pull in Procrastinate:
There are two ways to use the integration:
- Use the
ProcrastinateSystemIntegrationto automatically track all tasks on a ProcrastinateApp. - Use the
@trackdecorator on individual tasks you wish to track.
You can use both at the same time. The @track decorator is also useful when you want to access the
Task Badger task object within the body of a job.
Procrastinate System Integration
To track every task on a Procrastinate App, register the ProcrastinateSystemIntegration when
initializing Task Badger:
import taskbadger
from taskbadger.systems.procrastinate import ProcrastinateSystemIntegration
taskbadger.init(
token="YOUR_API_KEY",
systems=[ProcrastinateSystemIntegration(app=my_procrastinate_app)],
tags={"environment": "production"},
)
System Integration Options
The ProcrastinateSystemIntegration class takes the following parameters:
app: Theprocrastinate.Appinstance to instrument. Required.auto_track_tasks: Set this toFalseto disable automatic tracking of tasks. Tasks decorated with@trackwill still be tracked.includes: A list of task names or regex patterns to include. If this is set, only tasks that match one of the patterns will be tracked.excludes: A list of task names or regex patterns to exclude. If this is set, tasks that match one of the patterns will not be tracked.record_task_args: IfTrue, the job's keyword arguments will be recorded in the Task Badger task data underprocrastinate_task_kwargs.
Patterns are matched against the full task name using re.fullmatch. Exclusions take precedence over
inclusions, so if a task name matches both an include and an exclude, it will be excluded.
Procrastinate's built-in housekeeping tasks (those named builtin:... or procrastinate.*) are never
auto-tracked.
taskbadger.init(
token="YOUR_API_KEY",
systems=[ProcrastinateSystemIntegration(
app=app,
includes=[r"myapp\..*"],
excludes=[r"myapp\.cleanup\..*"],
record_task_args=True,
)],
)
Info
Construct the integration after all tasks and blueprints have been registered on the App.
Tasks added via app.add_tasks_from(blueprint) after the integration is constructed are not
auto-instrumented — apply @track to those tasks explicitly.
The track Decorator
To track individual tasks, or if you want access to the Task Badger task object within the body of a
job, apply the @track decorator outside (above) the @app.task decorator:
import procrastinate
from taskbadger.procrastinate import track
app = procrastinate.App(connector=...)
@track
@app.task(queue="default")
async def add(a, b):
return a + b
With this change a Task Badger task is created in the pending state when the job is deferred, and it
is updated to processing and then success or error as the worker runs it.
Tasks decorated with @track are always tracked, irrespective of the includes / excludes rules on
the ProcrastinateSystemIntegration.
Task Customization
The @track decorator accepts the following optional keyword arguments, applied when the Task Badger
task is created:
name: The Task Badger task name. Defaults to the Procrastinate task's name.value_max: The maximum value for the task.tags: A dictionary of tags applied to the task.data: A dictionary of initial data merged into the task.record_task_args: IfTrue, the job's keyword arguments are recorded underdata["procrastinate_task_kwargs"]. Defaults to inheriting the value from theProcrastinateSystemIntegrationif one is configured, otherwiseFalse.
@track(name="report", value_max=100, tags={"env": "prod"}, record_task_args=True)
@app.task
async def report(rows):
...
Accessing the Task Object
Use current_task() to get the Task Badger task for the currently-running job. This is useful for
updating progress or data from within the job body:
from taskbadger.procrastinate import track, current_task
@track
@app.task
async def report(rows):
tb = current_task()
for i, row in enumerate(rows):
await process(row)
if i % 10 == 0:
tb.update(value=i, value_max=len(rows))
Note
current_task() returns None outside of a tracked job, if Task Badger has not been
configured, or if the task could not be fetched.
Periodic Tasks
Periodic tasks scheduled with @app.periodic are tracked as well. Each periodic deferral creates a new
Task Badger task, so you can monitor the history and health of your scheduled jobs.
Queue Field
The name of the Procrastinate queue a task is deferred to is automatically recorded on the Task Badger
task's queue field.
Known Limitations
Procrastinate has no signals or middleware system, so the integration works by wrapping the task
function and the defer methods. This leads to a few cases that are not tracked:
task.configure(...).defer(...)is not tracked.configure()returns a separateJobDeferrerwhose methods bypass the wrapper. Usetask.defer(...)directly for tracked deferrals. Jobs deferred viaconfigure().defer()will still run normally, they just won't appear in Task Badger.task.batch_defer*is not tracked, for the same reason.- Tasks added via
app.add_tasks_from(blueprint)after theProcrastinateSystemIntegrationis constructed are not auto-instrumented. Construct the integration after all blueprints are registered, or apply@trackto those tasks explicitly.
Cancelled, aborted, and retried jobs surface as error in Task Badger.