npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

poli-c

v1.0.2

Published

A fault tolerance utility for JavaScript.

Downloads

118

Readme

Poli-C

GitHub license npm version

Poli-C (pronounced "policy") is a fault tolerance utility for JavaScript. Inspired by Polly for .NET, this library's aim is to help applications handle transient failures in asynchronous actions.

API Reference and Documentation

Supported Policies

  • RetryPolicy - Sometimes you just need to try again.
  • CircuitBreakerPolicy - Don't kick services while they are down.

Installation

Using yarn:

yarn add poli-c

Or npm:

npm install --save poli-c

Then if using TypeScript or a module bundler such as webpack:

import Policy from 'poli-c'; // TypeScript
import { Policy } from 'poli-c'; // ES6

// or if not using ES6 modules
const { Policy } = require('poli-c');

RetryPolicy Examples

Basic

Retry forever

import { Policy } from 'poli-c';

...

const policy = Policy.waitAndRetryForever({ sleepDurationProvider: 1000 });

async function fetchThings() {
	const response = await fetch('https://servicethatmightfail.com/v1/things');
	const things = await response.json();
	return things;
}

...
const things = await policy.executeAsync(fetchThings);
...

Or not

const policy = Policy.waitAndRetry({ retryCount: 3, sleepDurationProvider: 1000 });

...
const things = await policy.executeAsync(fetchThings)
...

Additionally, control when the policy retries on error

const policy = Policy
	.handleError(error => error instanceof FetchError)
	.waitAndRetryForever({ sleepDurationProvider: 1000 });

async function fetchThings() {
	const response = await fetch('https://servicethatmightfail.com/v1/things');
	if (response.status !== 404 && !response.ok) {
		// if the request fails the policy will execute the action again
		throw new FetchError(response);
	}

	// but if parsing the JSON fails the action won't be retried
	const things = await response.json();
	return things;
}

...
const things = await policy.executeAsync(fetchThings);

With cancellation

The asynchronous function will be passed a cancellation token if one is provided to executeAsync. This allows for a cooperative cancellation approach (borrowed from the .NET framework). If canceled, executeAsync will currently return undefined.

import { Policy, CancellationTokenSource } from 'poli-c';

...

const policy = Policy.waitAndRetryForever({ sleepDurationProvider: 1000 });

async function fetchThings(cancellationToken) {
	const response = await cancelableFetch('https://servicethatmightfail.com/v1/things', cancellationToken);
	const things = await response.json();
	return things;
}

...

const cts = new CancellationTokenSource();
const promise = policy.executeAsync(fetchThings, cts.token);

// eventually cancel the execution
const timeout = setTimeout(() => {
	cts.cancel();
}, maxRequestTime);

const things = await promise;
if (!things) {
	// canceled
} else {
	// not canceled
	clearTimeout(timeout);
}
...

Until a valid result is obtained

import { Policy } from 'poli-c';

...

const policy = Policy
	.waitAndRetryForever({ sleepDurationProvider: 1000 })
	.untilValidResult(job => job.isComplete);

async function getJob(jobId) {
	const response = await fetch(`https://jobService.com/v1/jobs/${jobId}`);
	const job = await response.json();
	return job;
}

async function waitForJobCompletion(newJob, cancellationToken) {
	const completedJob = await policy.executeAsync(() => getJob(newJob.id), cancellationToken);
}

With exponential backoff

The library includes two backoff algorithms (full and equal jitter as described here) that are available for use.

import { Policy, backoffs } from 'poli-c';

...

const policy = Policy.waitAndRetry({ retryCount: 3, sleepDurationProvider: backoffs.fullJitter });

async function fetchThings() {
	const response = await fetch('https://servicethatmightfail.com/v1/things');
	const things = await response.json();
	return things;
}

...
const things = await policy.executeAsync(fetchThings);
...

Additionally, a custom backoff algorithm can be used:

const policy = Policy.waitAndRetry({ retryCount: 3, sleepDurationProvider: ({ retryAttempt }) => 1000 * retryAttempt });

CircuitBreakerPolicy Examples

Basic

import { Policy } from 'poli-c'; // ES6

const policy = Policy
	.handleError(error => error instanceof FetchError)
	.circuitBreaker({
		samplingDurationMs: 5000,
		failureThreshold: 0.75,
		minimumThroughput: 4,
		breakDurationMs: 5000,
	});

async function fetchThings() {
	const response = await fetch('https://servicethatmightfail.com/v1/things');
	if (response.status !== 404 && !response.ok) {
		throw new FetchError(response);
	}

	const things = await response.json();
	return things;
}

...

try {
	const things = await policy.executeAsync(fetchThings);
	return things;
} catch (e) {
	// this error may have been thrown immediately by circuit breaker if the
	// failure threshold has been met in the sampling period
	log(e);
}

Need more information about different policies and their APIs? See the API Reference!