Giter VIP home page Giter VIP logo

rx-retry's Introduction

RX-Retry for JS and TS, using RxJS, support for Node.js & NestJS and browsers

Has default configuration of random-backoff retry and backoff retry

Read this article for more details: AWS Exponential Backoff and Jitter

Provide handling for Observables AND Promises retries, with a configurable delay between retries.


Installation

npm i rx-retry

Usage

import { resolveWithRetry, ResolveRetryConfig, retryBackoff } from 'rx-retry'
import { throwError } from 'rxjs'

// Use on a promise
;(() => {
    const prm = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new Error('Promise error'))
        }, 1000)
    })

    const configuration: ResolveRetryConfig = {
        timeoutTime: 5000, // set timeout to fail the promise and retry, default is 0
        useJitter: true, // backoff strategy with random + exponantial delay, default is true
        retryStrategy: {
            initialInterval: 1000, // ms
            maxRetries: 3,
            onRetry: (attempt: number, error: Error) => {
                console.log('Log this - retry') // adding action on retry
            },
            maxInterval: 10000, // ms
            shouldRetry: (error) => true, // check if retry needed, default is always true
        },
    }
    const res = await resolveWithRetry(prm, configuration)
})()

// Use on Observable, will be converted into promise
;(() => {
    const obs = throwError('Observable error')

    const configuration: ResolveRetryConfig = {
        timeoutTime: 5000, // set timeout to fail the promise and retry, default is 0
        useJitter: true, // backoff strategy with random + exponantial delay, default is true
        retryStrategy: {
            initialInterval: 1000, // ms
            maxRetries: 3,
            onRetry: (attempt: number, error: Error) => {
                console.log('Log this - retry') // adding action on retry
            },
            maxInterval: 10000, // ms
            shouldRetry: (error) => true, // check if retry needed, default is always true
        },
    }
    const res = await resolveWithRetry(obs, configuration)
})()

// Using the custom operator function in a pipe
;(() => {
    const obs = throwError('Observable error')

    obs.pipe(
        retryBackoff({
            initialInterval: 1000,
            maxInterval: 10000,
            maxRetries: 5,
        }),
    )
})()


Out of the box support for NestJS

Module sync configuration

import { Module } from '@nestjs/common'
import { TestingService } from './testing.service'
import { RxRetryModule } from 'rx-retry'

@Module({
    imports: [
        RxRetryModule.register({
            timeoutTime: 5000, // set timeout to fail the promise and retry, default is 0
            useJitter: true, // backoff strategy with random + exponantial delay, default is true
            retryStrategy: {
                initialInterval: 1000, // ms
                maxRetries: 3,
                maxInterval: 10000, // ms
                shouldRetry: (error) => true, // check if retry needed, default is always true
            },
            isGlobal: true, // set module as global
        }),
    ],
    providers: [TestingService],
})
export class TestingModule {}


Module async configuration

import { Module } from '@nestjs/common'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { TestingService } from './testing.service'
import { RxRetryModule } from 'rx-retry'

@Module({
    imports: [
        // setup for config module
        ConfigModule.forRoot({
            isGlobal: true,
            cache: true,
        }),

        RxRetryModule.registerAsync({
            inject: [ConfigService],
            isGlobal: true, // set module as global
            useFactory: async (conf: ConfigService) => {
                const configuration = {
                    timeoutTime: +conf.get('timeoutTime'), // set timeout to fail the promise and retry, default is 0
                    useJitter: !!conf.get('useJitter'), // backoff strategy with random + exponantial delay, default is true
                    retryStrategy: {
                        initialInterval: +conf.get('initialInterval'), // ms
                        maxRetries: +conf.get('maxRetries'),
                        maxInterval: 10000, // ms
                    },
                }

                return configuration
            },
        }),
    ],
    providers: [TestingService],
})
export class TestingModule {}


Service usage

import { Injectable } from '@nestjs/common'
import { RxRetryService } from 'rx-retry'
import { catchError, from, Observable, of, throwError } from 'rxjs'

@Injectable()
export class TestingService {
    constructor(private readonly rxRetry: RxRetryService) {}

    public resolveWithRetry() {
        return this.rxRetry.resolveWithRetry(this._getPromise())
    }

    // run over only for loggerInstance, passing it to log with it
    public runOverConfiguration() {
        return this.rxRetry.resolveWithRetry(this._getPromise(), {
            retryStrategy: {
                onRetry: (attempt: number, error: Error) => {
                    this.logger.log(`Retry attempt ${attempt}`)
                },
            },
        })
    }

    // Resolve Obsevable into promise with global config
    public resolveWithRetryObs() {
        return this.rxRetry.resolveWithRetry(this._getObs())
    }

    // Using the basic operator
    public resolveWithRetryObsPipe() {
        return this._getObs().pipe(
            retryBackoff({
                initialInterval: 1000,
                maxInterval: 10000,
                maxRetries: 5,
                onRetry: (attempt: number, error: Error) => {
                    console.log('attempt :>> ', attempt)
                },
            }),
        )
    }

    // Run over part of the main configuration
    public resolveWithRetryObsGlobal() {
        return this._getObs().pipe(
            this.rxRetry.resolveWithRetryOperator({
                initialInterval: 1000,
                onRetry: (attempt: number, error: Error) => {
                    this.logger.debug('attempt :>> ', attempt)
                },
            }),
        )
    }

    private _getObs() {
        return throwError('Observable error')
    }

    private _getPromise() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                const isOk = Math.random() > 0.5
                if (isOk) {
                    resolve('Promise resolved')
                    return
                }
                reject('Promise rejected')
            }, 1000)
        })
    }
}

rx-retry's People

Contributors

avivbens avatar dependabot[bot] avatar rocicorp-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

slavafomin

rx-retry's Issues

Can't compile for browser using webpack

Hello!

Thank you for this great library, it looks very promising!

However, you are currently exporting the Nest.js specific symbols (including the decorators) that break webpack builds for browser. Also, the bundles that you generate are not optimized for browsers (multiple common.js files instead of a tree-shakeable "FESM" [a single flat ESM module]).

If you are interested, I have an example project that is getting built for both Node.js and browser using the esbuild. Feel free to check it out/copy.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.