Javascript client for the Adobe Asset Compute Service. Currently only tested with Nodejs. The Javascript API is separated in 3 parts:
- AssetCompute - A light-weight wrapper around the AssetCompute API.
-
AssetComputeEventEmitter - Listens to an I/O event journal and converts the events to
rendition_created
andrendition_failed
events. -
AssetComputeClient - A higher level client that provides a simpler API
- by default, uses
node-fetch-retry
for retrying on other HTTP responses - by default, provides custom, smarter retry behavior on HTTP status code 429 (Too many requests).
- by default, uses
AssetComputeClient has the following capabilities:
- Fully initialize Asset Compute through a previously provisioned integration
- Listens to I/O events on the integration
- Invoke Asset Compute process asynchronously
- Wait for a single Asset Compute process request to finish (default timeout is 60s)
- Wait for all Asset Compute process requests to finish (default timeout is 60s)
retry
has the following capabilities:
- additional features to retry on 429s for
/unregister
,/register
, and/process
- Looks at the
retry-after
header in the HTTP response to determine how long to wait (in seconds) before retrying - If no
retry-after
is present, choose a random wait time between 30-60 seconds - Configurable retry count via
max429RetryCount
option. (Defaults to 4 retries) - Disable completely via the
disable429Retry
option. (Defaults to 4 retries)
npm i @adobe/asset-compute-client
After the client is set up, you must call .register()
once before the first call to .process()
.
If the integration does not already have an I/O Events journal registered, it may take some time after calling .register()
to be able to recieve and send I/O Events so it is recommended to add some wait time before calling .process()
.
If the integration already has an I/O Events journal registered, it is recommended to not wait before calling .process()
.
const { AssetComputeClient, getIntegrationConfiguration } = require("@adobe/asset-compute-client");
const sleep = require('util').promisify(setTimeout);
//If integration file is json, a private key file must also be provided
const integrationFilePath = "/path/to/integration/file"; // Either json or yaml format
const integration = await getIntegrationConfiguration(integrationFilePath[, privateKeyFile]);
const assetCompute = new AssetComputeClient(integration);
// Call register before first call the process
await assetCompute.register();
// add wait time for events provider to set up
await sleep(45000); // 30s
const { requestId } = await assetCompute.process(
"https://presigned-source-url", [
{
name: "rendition.png",
url: "https://presigned-target-url",
fmt: "png",
width: 200,
height: 200
}
]
)
const events = await assetCompute.waitActivation(requestId);
if (events[0].type === "rendition_created") {
// use the rendition
} else {
// failed to process
}
Note that any errors while polling the I/O Event journal will be logged before it retries:
Error polling event journal: request to https://events-va6.adobe.io/.... failed, reason: connect ECONNREFUSED 54.81.231.29:443
To add custom error message handling, listen for the error
event:
assetCompute.on("error", error => console.log("custom error message", error.message));
Or disable any error message output:
assetCompute.on("error", () => {});
This function creates a new instance of AssetComputeClient
and calls the .register()
method.
const { AssetComputeClient, getIntegrationConfiguration } = require("@adobe/asset-compute-client");
//If integration file is json, a private key file must also be provided
const integrationFilePath = "/path/to/integration/file"; // Either json or yaml format
const integration = await getIntegrationConfiguration(integrationFilePath[, privateKeyFile]);
const assetCompute = await AssetComputeClient.create(integration);
// add wait time if needed
const { requestId } = await assetCompute.process(
"https://presigned-source-url", [
{
name: "rendition.png",
url: "https://presigned-target-url",
fmt: "png",
width: 200,
height: 200
}
]
)
const events = await assetCompute.waitActivation(requestId);
if (events[0].type === "rendition_created") {
// use the rendition
} else {
// failed to process
}
After setting up the client, it is necessary to call .register()
once before calling .process()
.
If the integration already has an I/O Events journal registered, you still must call register. The journal url returned from register is necessary for the client to retrieve I/O Events.
If the integration does not have an I/O Events journal registered, make sure to add some wait time after calling .register()
before calling .process()
. (It is recommended to wait around ~45 seconds)
const assetCompute = new AssetComputeClient(integration);
await assetCompute.register();
The unregister method will remove the I/O Events Journal created in .register()
. It is necessary to call .register()
again before attempting to use the client after unregistering.
Example usage:
const assetCompute = new AssetComputeClient(integration);
await assetCompute.register();
await assetCompute.process(..renditions);
// unregister journal
await assetCompute.unregister();
// call to process will fail, must call `register()` again first
try {
await assetCompute.process(..renditions);
} catch (e) {
// expected error, must call `register()` first
}
await assetCompute.register();
sleep(45000); // sleep after registering to give time for journal to set up
await assetCompute.process(..renditions);
By default, AssetComputeClient
will retry 4 times (with smart backpressure) on 429s.
Retry 10 times on 429s:
const assetCompute = new AssetComputeClient(integration, {
max429RetryCount: 10
});
Disable retry on 429s:
const assetCompute = new AssetComputeClient(integration, {
disable429Retry: false
});
Fetch retry options are documented here. The default options are used on each fetch request.
Note: these do not cover retrying on 429s since this requires the custom retry logic (retry.js) (ie, retrying every 1s with backoff could worsen the issue in a situation when the endpoint is overloaded)
Contributions are welcomed! Read the Contributing Guide for more information.
This project is licensed under the Apache V2 License. See LICENSE for more information.