How to Call Long-running Functions Asynchronously

Functions are blocks of code that run on demand without the need to manage any infrastructure. Develop on your local machine, test your code from the command line (using doctl), then deploy to a production namespace or App Platform — no servers required.


You can invoke long-running functions asynchronously using the doctl command line tool or the Functions REST API. You cannot run functions invoked as web functions asynchronously.

Asynchronous (or non-blocking) function invocations immediately return an activation ID, which you can then use to retrieve the function’s activation record, which includes the function’s output.

Synchronous (or blocking) function invocations are automatically converted to asynchronous if execution takes longer than 30 seconds. The converted function returns an activation ID and behaves exactly as if it had been called asynchronously from the start.

Call a Function Asynchronously using doctl

To call a function asynchronously using doctl, use the doctl serverless functions invoke command with the --no-wait flag:

doctl serverless functions invoke <your-function-name> --no-wait

Replace <your-function-name> with the name of your function, including the package name if necessary.

Note
Be sure you are connected to the correct Functions namespace when running the above command. Use doctl serverless namespaces list to list all of your namespaces, and doctl serverless connect <example-namespace> to connect to the namespace containing your function.

The command immediately returns a JSON object containing an activation ID:

{
  "activationId": "b68492d6875840148492d687586014f5"
}

The next section shows how to use this ID to retrieve the activation record.

Retrieve Activation Records Using doctl

Use the doctl serverless activation get command with an activation ID to retrieve the activation record:

doctl serverless activation get <your-activation-id>

Substitute your activation ID in this command.

If the function invocation is complete, it returns the full activation record as JSON. This record contains the output of the function along with other information about the process. See the Activation Record reference for more details.

{
  "namespace": "fn-378ae839-e58b-4cd1-afcf-632cd7b7b8db",
  "name": "sample/hello",
  "version": "0.0.1",
  "subject": "da25db4890885df62c1bfb6afdb4c91cb3b4bca5",
  "activationId": "b68492d6875840148492d687586014f5",
  "start": 1692623022053,
  "end": 1692623024056,
  "duration": 2002,
  "statusCode": 0,
  "response": {
    "status": "success",
    "statusCode": 0,
    "success": true,
    "result": {
      "body": "Hello stranger!"
    }
  },
  // . . .

If the function is still running, the activation record does not yet exist and the command returns an error message. Additionally, the doctl command exits with an exit code of 1, indicating an error occurred:

Error: The requested activation record does not exist. This either means that the invocation is still running and the record is not yet created or the activation's retention period has already expired.

The retention period for activation records is at least 72 hours. If you see this error and your activation ID is less than 72 hours old, your function is still running and no activation record exists yet. Wait for your function to finish and then try again.

To retrieve only the response from your function with no additional process information, use result instead of get in the doctl command:

doctl serverless activation result <your-activation-id>
{
  "body": "Hello stranger!"
}

Both get and result support using the --last flag instead of specifying an activation ID. This returns the most recent activation record or result in the current namespace:

doctl serverless activation result --last

The command prints an activation header, followed by the result:

=== b68492d6875840148492d687586014f5 success 02/01 12:33:17 hello:0.0.12
{
  "body": "Hello stranger!"
}

To get only the result with no header, add the -q or --quiet flag:

doctl serverless activation result --last -q

The command prints the result only:

{
  "body": "Hello stranger!"
}

Call a Function Asynchronously using curl and the REST API

To call a function asynchronously using curl or any other HTTP client or library, use the Functions REST API. To find your function’s REST API URL and authorization token, navigate to the function in the DigitalOcean Control Panel, then click on the function’s Settings tab.

In the Access & Security section, under REST API, click the Show Token link and copy the entire curl command.

The settings tab of an individual function, showing the Access & Security section with Web and REST API URLs listed

Here is an example of the copied curl command:

curl -X POST "https://faas-EXAMPLE-2ef2e6cc.doserverless.co/api/v1/namespaces/fn-EXAMPLE-632cd7b7b8db/actions/sample/hello?blocking=true&result=true" \
  -H "Content-Type: application/json" \
  -H "Authorization: MWMwEXAMPLEXckk="

Your command has a different server name (faas-EXAMPLE-2ef2e6cc), namespace ID (fn-EXAMPLE-632cd7b7b8db), and token.

The copied command sends a POST request to your function with the options blocking=true&result=true appended as an HTTP query string.

The blocking=true option instructs the runtime to run this function synchronously. Change this to blocking=false to instead invoke the function asynchronously.

Remove the result=true option because it doesn’t apply to asynchronous function invocations. Now the curl command looks like this:

curl -X POST "https://<your-server>.doserverless.co/api/v1/namespaces/<your-namespace>/actions/sample/hello?blocking=false" \
  -H "Content-Type: application/json" \
  -H "Authorization: <your-token>"

Run the curl command using your own URL pointing to your server and namespace, and with your authorization token.

The Functions service immediately returns an activation ID:

{
  "activationId": "b68492d6875840148492d687586014f5"
}

You can get the activation record using doctl as shown in the previous section or use another REST API call as described in the following section.

Retrieve Activation Records Using curl and the REST API

From the REST API URL you used in the previous section, remove the /actions/sample/hello... portion, and replace it with /activations/<your-activation-id>. Also switch curl’s request type from POST to GET:

curl -X GET "https://<your-server>.doserverless.co/api/v1/namespaces/<your-namespace>/activations/<your-activation-id>" \
        -H "Authorization: Basic <your-token-here>"

Run the curl command after replacing the placeholders with your server, namespace, and authorization token.

If the function invocation is complete, the API returns the full activation record as JSON. This record contains the output of the function along with other information about the process. See the Activation Record reference for more details.

{
  "namespace": "fn-378ae839-e58b-4cd1-afcf-632cd7b7b8db",
  "name": "sample/hello",
  "version": "0.0.1",
  "subject": "da25db4890885df62c1bfb6afdb4c91cb3b4bca5",
  "activationId": "b68492d6875840148492d687586014f5",
  "start": 1692623022053,
  "end": 1692623024056,
  "duration": 2002,
  "statusCode": 0,
  "response": {
    "status": "success",
    "statusCode": 0,
    "success": true,
    "result": {
      "body": "Hello stranger!"
    }
  },
  // . . .

If the function is still running, the activation record does not exist yet, and the API returns an error message:

{
  "code": "338d3285577add412cf6dee4e0a1fc9f",
  "error": "The requested activation record does not exist. This either means that the invocation is still running and the record is not yet created or the activation's retention period has already expired."
}

The retention period for activation records is 72 hours. If you see this error and your activation ID is less than 72 hours old, your function is still running and no activation record exists yet. Wait for your function to finish and then try again.

You can also list out multiple recent activations by leaving the activation ID off of the URL. Optionally, you can limit the list size using ?limit=<number>. The following curl command lists the last three activations in the specified namespace:

curl -X GET "https://<your-server>.doserverless.co/api/v1/namespaces/<your-namespace>/activations?limit=3" \
        -H "Authorization: Basic <your-token>"

Retrieve Activation Records Using the Control Panel

You can also find activation records in the DigitalOcean Control Panel. Navigate to the Functions namespace containing your function, then click on the Logs tab:

The Logs tab of an individual function, showing the Function and Period selection dropdowns, and a list of logs

You can view all activations in the namespace or filter based on function name and time period. Click the [+] button next to an activation to see the full activation record details.