Background Action Handle - BackgroundActionHandle 

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.

JavaScript
const handle = await api.enqueue(api.myAction, {}); console.log(handle.id); // => "app-job-abc123"
const handle = await api.enqueue(api.myAction, {}); console.log(handle.id); // => "app-job-abc123"

handle.result(options) 

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
JavaScript
const handle = await api.enqueue(api.widget.update, { id: "123", name: "updated" }); // select specific fields from the result const widget = await handle.result({ select: { id: true, name: true, gizmos: { edges: { node: { id: true } } }, }, });
const handle = await api.enqueue(api.widget.update, { id: "123", name: "updated" }); // select specific fields from the result const widget = await handle.result({ select: { id: true, name: true, gizmos: { edges: { node: { id: true } } }, }, });

Returns 

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.

JavaScript
const handle = await api.enqueue(api.myAction, { /* params */ }); // cancel the action await handle.cancel();
const handle = await api.enqueue(api.myAction, { /* params */ }); // cancel the action await handle.cancel();

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:

StatusDescription
scheduledThe action is scheduled to run in the future
waitingThe action is ready to start and waiting for a worker
retryingThe action is scheduled to retry after a previous failure
runningThe action is currently executing
completedThe action finished successfully
failedThe action failed and will not retry
cancelledThe 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.

Was this page helpful?