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

node-circuit-breaker

v0.1.1

Published

Circuit Breaker: Decorators and tools that can easily apply the Circuit Breaker pattern.

Downloads

5

Readme

Circuit Breaker

  • Circuit Breaker pattern을 쉽게 적용할 수 있는 Decorator
  • Node version >= 16
    • Worker thread, BroadcastChannel를 활용합니다.

Node.js CI NPM Version License

Install

  • NPM
$ npm install node-circuit-breaker --save
  • Yarn
$ yarn add node-circuit-breaker
  • Error Wrapper를 활용하기 위해 axios, @nestjs/common, typeorm 패키지가 추가로 필요할 수 있습니다.

API

@CircuitBreaker Method Decorator

  • Options

| Member | Sub | Type | Required | Description | |-----------------------|:-------------|----------------------------------------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | fallback | | Function string Object | required | CircuitBreaker state:Open 상태일 때 반환할 오류 또는 실행할 함수Function : 지정된 함수를 대신 실행합니다.String : 대신 실행할 현재 컨텍스트의 객체 내의 다른 method의 이름.eg) xxxxFallbackObject : 지정된 값을 즉시 응답합니다. | | rules | | Array<CircuitBreakerRule> | required | state:Open을 판단하기 위한 규칙들 | | | exceptions | Array<typeof Error> | required | Exception 목록 | | | times | number | required | 기준 시간 내 exception 횟수 | | | inSeconds | number | required | 기준 시간(초) | | fallbackForSeconds | | number | required | state:Open -> state:HalfOpen 전까지 fallback으로 응답할 시간(초) | | timeoutMilliSeconds | | number | | method의 실행이 지정된 시간(ms)보다 오래 걸릴 경우 내부적으로 ExecutionTimeoutError를 생성한다. rules 내에 ExecutionTimeoutError를 정의하여 CircuitBreaker에 영향을 줄 수 있다. | | scope | | CircuitBreakerScope | | CircuitBreakerScope.DEFAULT : 컨텍스트를 무시하고 해당 method에서 발생하는 exception을 모두 catchCircuitBreakerScope.INSTANCE : 인스턴스 컨텍스트 내의 method에서 발생하는 exception만 catch | | onCircuitOpen | | (circuit: Circuit) => Promise<boolean> | | state:Open이 될 때 호출되는 콜백. false를 리턴할 경우 state 변경이 되지 않는다. | | onCircuitClose | | (circuit: Circuit) => Promise<boolean> | | state:Close가 될 때 호출되는 콜백. false를 리턴할 경우 state 변경이 되지 않는다. | | ignore | | (error: any, circuit: Circuit) => Promise<boolean> | | 에러가 발생했을때 호출되는 콜백. true가 리턴되면 에러가 무시되며, circuit에 영향을 주지 않는다. | | onError | | (error: any, circuit: Circuit) => Promise<void> | | 에러가 발생했을때 호출되는 콜백. |

CircuitBreakerManager

  • CircuitBreakerManager.terminate()
    • CircuitBreaker Worker를 종료합니다. Worker가 종료되면 Circuit state 변경이 중지됩니다.

Usage

class Test {
  @CircuitBreaker({
    // state:Open일 경우 같은 인스턴스 내의 test1Fallback(...)를 실행합니다.
    fallback: 'test1Fallback',
    rules: [
      // TypeormQueryTimeoutError, RequestTimeoutException, GatewayTimeoutException
      // 에러가 60초 내에 10회 발생할 경우 state:Open이 되며 fallback이 수행됩니다. 
      {
        exceptions: [TypeormQueryTimeoutError, RequestTimeoutException, GatewayTimeoutException],
        times: 10,
        inSeconds: 60
      },
      // BadGatewayException, TypeormConnectionFailedError, ServiceUnavailableException
      // 에러가 5초 내에 30회 발생할 경우 state:Open이 되며 fallback이 수행됩니다.
      {
        exceptions: [BadGatewayException, TypeormConnectionFailedError, ServiceUnavailableException],
        times: 30,
        inSeconds: 5
      }
    ],
    // state:Open이 된 후 5초 후에 state:HalfOpen 상태가 되며 일부 호출이 정상적으로 수행됩니다.
    // 이 때 에러가 발생하는 경우 다시 state:Open으로 변경되며 5초 후에 다시 state:HalfOpen으로 변경됩니다.
    // state:HalfOpen 상태에서 정상적인 응답을 한 경우 state:Closed 상태가 됩니다.
    fallbackForSeconds: 5,
  })
  test1(arg: string) {
    if (arg === 'error') throw new BadGatewayException();
    return arg;
  }

  test1Fallback(arg: string) {
    return 'fallback';
  }

  @CircuitBreaker({
    scope: CircuitBreakerScope.INSTANCE,
    fallback: TestFallback.test2,
    // method의 수행이 1000ms 이상이 걸리게 되면 ExecutionTimeoutError 에러가 기록됩니다.
    // ExecutionTimeoutError는 throw 되지 않으며 circuit breaker 내부로만 전달됩니다.
    timeoutMilliSeconds: 1000,
    rules: [
      { exceptions: [BadGatewayException], times: 10, inSeconds: 5 },
      { exceptions: [ExecutionTimeoutError], times: 3, inSeconds: 10 }
    ],
    fallbackForSeconds: 3,
  })
  test2(arg: string) {
    if (arg === 'error') throw new BadGatewayException();
    return arg;
  }
}

class TestFallback {
  static test2(arg: string) {
    return arg;
  }
}

Contributors


Error Wrapper

  • 자주 쓰이는 기능들의 error wrapper를 제공합니다.
  • 제공되는 Error Wrapper와 모든 종류의 Error를 @CircuitBreaker({ rules[].exceptions[...] })로 catch할 수 있습니다.

ExecutionTimeoutError

  • @CircuitBreaker({...})timeoutMilliSeconds를 설정한 경우, 설정된 시간보다 해당 method 수행 시간이 긴 경우 ExecutionTimeoutError가 발생합니다.

TypeORM

  • typeorm이 설치된 경우 QueryFailedError를 세분화합니다.
  • SQL 질의가 실패한 경우 접속 이슈인지 타임아웃인지 여부를 구분하여 에러를 캐치할 수 있습니다.

| Source Error | Converted | Condition | |--------------------|--------------------------------|---------------------------------------------------------| | QueryFailedError | TypeormConnectionFailedError | QueryFailedError.driverErrorconnection 단어가 포함된 경우 | | QueryFailedError | TypeormQueryTimeoutError | QueryFailedError.driverErrortimeout 단어가 포함된 경우 |

Axios -> Nestjs HttpException

  • Axios는 에러 발생 시 AxiosError 한가지 형태로 에러를 반환하기 때문에 exception filter에 활용하기 어렵습니다.
  • AxiosError를 Nestjs의 HttpException 형태로 변환하여 CircuitBreaker의 룰로 활용하면 세밀한 룰 설정이 가능합니다.
  • axios, @nestjs/common 패키지가 필요합니다.
  • 변환 규칙들