Product
Socket Now Supports uv.lock Files
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
@azure/core-lro
Advanced tools
The @azure/core-lro package provides a framework for building and working with long-running operations (LROs) in Azure services. It offers a standardized way to poll for the status of these operations and retrieve the final results, abstracting the complexity involved in handling LROs.
Creating and managing long-running operations
This feature allows developers to implement custom pollers for managing long-running operations. The code sample demonstrates how to extend the Poller class to create a custom LRO poller.
const { Poller } = require('@azure/core-lro');
class MyLroPoller extends Poller {
async cancelOperation() {
// Cancel the operation if supported
}
async delay() {
// Implement delay between polls
}
}
const myPoller = new MyLroPoller();
await myPoller.pollUntilDone();
Polling for operation status
This feature enables polling for the status of a long-running operation until it is completed. The code sample shows how to use the Poller class to poll an operation until it's done.
const { Poller } = require('@azure/core-lro');
async function pollOperation(operation) {
const poller = new Poller({
operation,
});
return await poller.pollUntilDone();
}
The 'async' package provides utilities for working with asynchronous JavaScript, including control flow, iteration, and utilities functions. While it doesn't specifically target long-running operations, it offers tools that could be used to manage asynchronous tasks and operations, which could indirectly support LRO scenarios. However, it lacks the direct LRO management and polling capabilities of @azure/core-lro.
RxJS is a library for reactive programming using Observables, to make it easier to compose asynchronous or callback-based code. This can be particularly useful for managing streams of events or asynchronous tasks, which could include long-running operations. However, RxJS does not provide specific abstractions for LROs like @azure/core-lro does, focusing instead on a broader set of reactive programming tools.
Azure's Core LRO is a JavaScript library that provides an API that aims to allow the azure-sdk-for-js public libraries to implement fully featured pollers to manage Long Running Operations (LROs) with the Azure services.
@azure/core-lro is made following our guidelines here: https://azure.github.io/azure-sdk/typescript_design.html#ts-lro
To install this package locally, use npm install --save @azure/core-lro
.
TypeScript users need to have Node type definitions installed:
npm install @types/node
They will also need to enable compilerOptions.allowSyntheticDefaultImports
in their
tsconfig.json
. Note that if you have enabled compilerOptions.esModuleInterop
,
allowSyntheticDefaultImports
is enabled by default.
See TypeScript's compiler options handbook
for more information.
@azure/core-lro makes a distinction between the Long Running Operation and its Poller.
You will be able to find some working examples of an implementation of an operation and a poller both in our test files: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/core/core-lro/test as well as in the azure-sdk-for-js libraries that might be currently using core-lro, which can be found here: https://github.com/Azure/azure-sdk-for-js/search?q="from+%40azure%5C%2Fcore-lro"&unscoped_q="from+%40azure%5C%2Fcore-lro"
To work with a Long Running Operation, we need to define how to update, cancel and serialize the information related to the remote pending task. To implement this class for your library or application, you'll need to import the definitions of a poll operation and its state.
import { PollOperationState, PollOperation } from "@azure/core-lro";
A PollOperation
is an interface that defines how to update the local reference of the state
of the remote long running operation, just as well as how to request the cancellation of the same operation.
Besides updating and cancelling, it also defines how to serialize its information,
so that polling can be resumed at any time from a previously serialized operation
(more at Serializing an operation).
PollOperationState
provides a basic state for the poll operation.
It contains the minimal set of properties needed
to keep track of a long running operation, and it's intended to be extended
with any custom property that your program might need.
The state can be updated any time, but it should be updated at least in three opportunities:
when the operation starts, when it's finished, and when it's cancelled.
To be able to create your custom operations, you'll need to extend the
PollOperation
class with both your operation's state and the final result
value. For this example, we'll think on the final result value to be MyResult
,
which can be any type.
import { PollOperationState, PollOperation } from "@azure/core-lro";
export interface MyOperationState extends PollOperationState<MyResult> {
serviceClient: any; // You define all of these properties
myCustomString: string;
startedAt: Date;
finishedAt: Date;
// ... and so on
}
export interface MyPollOperation extends PollOperation<MyOperationState, MyResult> {}
We recommend making a utility function to create new instances of your operation. Just like the following:
function makeOperation(
state: MyOperationState,
): MyOperation {
return {
// We recommend creating copies of the given state,
// just to make sure that no references are left or manipulated by mistake.
state: {
...state,
},
update,
cancel,
toString
};
}
To properly define an operation, you will need to have implemented these three functions: update
, cancel
and toString
.
A guide on how to write them follows.
The update
method defines how to request the remote service for updates on the status of the long running operation.
It optionally receives an object with an abortSignal
property, from @azure/abort-controller's AbortSignalLike
.
A more advanced use allows passing in a fireProgress
function, which, if called, is responsible for triggering the
poller's onProgress
callbacks.
Here is an example of how to write an update method for your operation:
async function update(
this: MyOperation,
options: {
abortSignal?: AbortSignalLike;
fireProgress?: (state: MyOperationState) => void;
} = {}
): Promise<MyOperation> {
let isDone: boolean = false;
let doFireProgress: boolean = false;
// Asynchronously call your service client...
// You might update the operation's state at any point
if (isDone) {
this.state.completed = true;
this.state.result = "Done";
}
// You can also arbitrarily report progress
if (doFireProgress) {
options.fireProgress(state);
}
return makeOperation(this.state);
}
The operation's cancel
method should attempt to cancel the pending operation, if it's allowed by the remote service.
Otherwise, it should throw.
It only optionally receives an object with an abortSignal
property, from @azure/abort-controller's AbortSignalLike
.
It returns a promise that should be resolved with an updated version of the poller's operation.
async function cancel(
this: MyOperation,
options: { abortSignal?: AbortSignalLike } = {}
): Promise<MyOperation> {
// ... Reach out to your service to trigger the cancellation of the operation ...
return makeOperation(
{
...this.state,
cancelled: true
}
);
}
The operation's method toString
returns a string with a serialized representation of the operation.
It's useful when a poller wants to be resumed from a previously serialized state.
The deserialization of the operation has to be implemented within the constructor of a class that extends the Poller class. You can read more at Resuming from a previous poller.
function toString(this: MyOperation): string {
return JSON.stringify({
state: {
...this.state,
// Only the plain text properties, for example
}
});
}
@azure/core-lro's Poller
is a class that represents the definition of a program that polls
through consecutive requests until it reaches a state of completion.
A poller can be executed manually, by polling request by request by calling to the poll()
method repeatedly,
until its operation is completed.
It also provides a way to wait until the operation finishes, by calling pollUntilDone()
, which returns a promise.
Pollers can also request the cancellation of the ongoing process (internally using PollOperation
's cancel()
method).
The Poller needs two types to be defined, a type representing the state of the poller, which
must include a basic set of properties from PollOperationState<TResult>
(as mentioned in Implementing an operation), and a return type defined by TResult
, which can be anything.
To implement a poller, you must pull in the definitions of your operation and extend @azure/core-lro's Poller
class, as follows:
import { Poller } from "@azure/core-lro";
import { makeOperation, MyOperation, MyOperationState } from "./myOperation";
// See that "MyResult" here is the type of the result
export class MyPoller extends Poller<MyOperationState, MyResult> {
constructor(
baseOperation?: MyOperation,
onProgress?: (state: MyOperationState) => void
) {
let state: MyOperationState = {};
if (baseOperation) {
state = baseOperation.state;
}
const operation = makeOperation(state);
super(operation);
// Setting up the poller to call progress when the operation decides.
// This ties to the operation's update method, which receives a
// fireProgress method in the optional properties.
if (onProgress) {
this.onProgress(onProgress);
}
}
async delay(): Promise<void> {
// Your own implementation of a delay
}
}
Once defined, you'll be able to use your poller as shown below:
const poller = new MyPoller();
// Polling just once:
await poller.poll();
// We can try to cancel the request here, by calling:
//
// await poller.cancelOperation();
//
// Getting the final result:
const result = await poller.pollUntilDone();
The Poller class implements the PollerLike
interface, which allows poller implementations that avoid having
to export the Poller's class directly, and instead only export the already instantiated poller with the PollerLike
type.
An example of the definition of a client that returns an instantiated poller can be seen below:
class Client {
public async makePoller: PollerLike<MyOperationState, MyResult> {
const poller = new MyPoller({});
// It might be preferred to return the poller after the first request is made,
// so that some information can be obtained right away.
await poller.poll();
return poller;
}
}
// No knowledge of the class MyPoller:
const poller: PollerLike<MyOperationState, MyResult> = myClient.makePoller();
A poller can be created through its constructor, then it can be polled until it's completed. At any point in time, the state of the poller can be obtained without delay through the getOperationState method. At any point in time, the intermediate forms of the result type can be requested without delay. Once the underlying operation is marked as completed, the poller will stop and the final value will be returned.
Here's an example usage of your client's poller:
const poller = myClient.makePoller();
const state: MyOperationState = poller.getOperationState();
// The intermediate result can be obtained at any time.
const result: MyResult | undefined = poller.getResult();
// The final result can only be obtained after the poller finishes.
const result: MyResult = await poller.pollUntilDone();
Pollers by default have a method called toString
that invokes the operation's toString
method.
It can be used to store the state of a poller indefinitely, to then resume by creating another poller at any time in the future.
If an operation's toString
method is defined as follows:
function toString(this: TestOperation): string {
return JSON.stringify({
state: this.state
});
}
A custom implementation of a poller can deserialize it by receiving this string and converting it back to JSON, like in the following example:
export class MyPoller extends Poller<MyOperationState, string> {
constructor(
baseOperation: string | undefined
) {
let state: MyOperationState = {};
if (baseOperation) {
state = {
...JSON.parse(baseOperation).state,
...state
};
}
const operation = {
state,
// ...
}
super(operation);
}
}
Logs can be added at the discretion of the library implementing the Long Running Operation poller. Packages inside of azure-sdk-for-js use @azure/logger.
Please take a look at the samples directory for detailed examples on how to use this library.
This project welcomes contributions and suggestions. Please read the contributing guidelines for detailed information about how to contribute and what to expect while contributing.
To run our tests, first install the dependencies (with npm install
or rush install
),
then run the unit tests with: npm run unit-test
.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
FAQs
Isomorphic client library for supporting long-running operations in node.js and browser.
The npm package @azure/core-lro receives a total of 1,637,403 weekly downloads. As such, @azure/core-lro popularity was classified as popular.
We found that @azure/core-lro demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.