When you enqueue a background action in Forgelivo, you receive a BackgroundActionHandle object. This handle allows you to interact with the enqueued action: you can check its status, wait for its result, or cancel it.
Getting a handle
You can get a BackgroundActionHandle in two ways:
When enqueuing an action
The api.enqueue() function returns a handle for the newly enqueued action:
JavaScript
// enqueue an action and get a handle
const handle = await api.enqueue(api.myAction, {
/* params */
});
// the handle has the action's unique ID
console.log(handle.id); // => "app-job-abc123"
// enqueue an action and get a handle
const handle = await api.enqueue(api.myAction, {
/* params */
});
// the handle has the action's unique ID
console.log(handle.id); // => "app-job-abc123"
For an existing action
If you have the ID of a previously enqueued action, you can create a handle using api.handle():
JavaScript
// create a handle for an existing background action
const handle = api.handle(api.myAction, "app-job-abc123");
// now you can interact with it
const status = await handle.status();
// create a handle for an existing background action
const handle = api.handle(api.myAction, "app-job-abc123");
// now you can interact with it
const status = await handle.status();
This is useful when you have stored the background action ID (for example, on a record) and need to check on it later.
BackgroundActionHandle API
handle.id
The unique identifier for this background action. This ID is assigned when the action is enqueued and can be used to create a handle later or to look up the action in the Queues dashboard.
Waits for the background action to complete and returns the result. If the action fails after all retries, this method throws the final error.
JavaScript
const handle = await api.enqueue(api.widget.create, { name: "foo" });
// wait for the action to complete and get the result
const widget = await handle.result();
console.log(widget.id);
const handle = await api.enqueue(api.widget.create, { name: "foo" });
// wait for the action to complete and get the result
const widget = await handle.result();
console.log(widget.id);
Parameters
options (optional): An object with the following properties:
select - For model actions, select specific fields to return from the result record
Returns a Promise that resolves with the action result when completed, or rejects with an error if the action fails.
Since handle.result() waits for completion, it can take time depending on retry schedules. If an action has a large backoffFactor,
high retryCount, and high maxInterval, it may take hours or even days to return a result.
handle.cancel()
Cancels a scheduled or running background action. When cancelled, the action will not execute any further retry attempts.
Background actions in the scheduled, waiting, running, or retrying states can be cancelled. Cancelled actions will have their status set to cancelled.
Returns
Returns a Promise<void> that resolves when the action has been cancelled.
Cancelling a running action sends an abort signal to the action. For the action to actually stop executing, you need to handle the abort
signal in your action code. See the Background actions guide for more details.
handle.status()
Fetches the current status of the background action without waiting for it to complete. This is useful for displaying progress indicators or making decisions based on whether an action is still running.
JavaScript
const handle = await api.enqueue(api.myAction, {
/* params */
});
// check the current status without waiting
const status = await handle.status();
if (status === "running") {
console.log("Action is still in progress");
} else if (status === "completed") {
console.log("Action has finished successfully");
}
const handle = await api.enqueue(api.myAction, {
/* params */
});
// check the current status without waiting
const status = await handle.status();
if (status === "running") {
console.log("Action is still in progress");
} else if (status === "completed") {
console.log("Action has finished successfully");
}
Returns
Returns a Promise<string> that resolves with one of the following status values:
Status
Description
scheduled
The action is scheduled to run in the future
waiting
The action is ready to start and waiting for a worker
retrying
The action is scheduled to retry after a previous failure
running
The action is currently executing
completed
The action finished successfully
failed
The action failed and will not retry
cancelled
The action was cancelled
Unlike handle.result(), the status() method returns immediately with the current status and does not wait for the action to complete.
Storing handle IDs
A common pattern is to store the background action ID on a record so you can retrieve the handle later:
api/models/post/actions/create.js
JavaScript
export const onSuccess: ActionOnSuccess = async ({ record, api }) => {
// enqueue a publish action to run in 5 minutes
const handle = await api.enqueue(
api.post.publish,
{ id: record.id },
{ startAt: new Date(Date.now() + 5 * 60000) }
);
// store the background action ID on the record
record.backgroundActionId = handle.id;
await save(record);
};
export const onSuccess: ActionOnSuccess = async ({ record, api }) => {
// enqueue a publish action to run in 5 minutes
const handle = await api.enqueue(
api.post.publish,
{ id: record.id },
{ startAt: new Date(Date.now() + 5 * 60000) }
);
// store the background action ID on the record
record.backgroundActionId = handle.id;
await save(record);
};
Later, you can retrieve the handle and interact with it:
api/models/post/actions/cancelPublish.js
JavaScript
export const run: ActionRun = async ({ record, api }) => {
// get a handle for the stored background action
const handle = api.handle(api.post.publish, record.backgroundActionId!);
// cancel the scheduled publish
await handle.cancel();
// clear the stored ID
record.backgroundActionId = null;
await save(record);
};
export const run: ActionRun = async ({ record, api }) => {
// get a handle for the stored background action
const handle = api.handle(api.post.publish, record.backgroundActionId!);
// cancel the scheduled publish
await handle.cancel();
// clear the stored ID
record.backgroundActionId = null;
await save(record);
};
Permissions
To access the result or status of a background action, the requesting api client must have the same identity as the client that enqueued the action. This means that unauthenticated users cannot access the results of actions enqueued by other users.
If you need to make background action results accessible to more users, store the result on a data model and use the normal access control system to grant access.