반응형

https://chunghyup.tistory.com/50

 

[Pattern]Circuit Breaker Pattern - 회로 차단 패턴

MSA 방식의 아키텍쳐를 택한 서비스를 개발하는 중 아래와 같이 다른 MS(Micro Service)를 호출하는 경우는 상당히 많다. 1 2 const authService = new AuthService() authService.login(loginDto) cs 오류 처..

chunghyup.tistory.com

위 게시물과 연결되는 내용입니다.

 

JS를 이용하여 간다하게 Circuit Breaker를 구현해보았다.

 

몇번 실패를 하면 Open을 할 것인지, 몇 초 후 halfOpen으로 만들것인지 두가지 기능만 구현을 해 놓았다.

 

직접 사용하며 추가로 필요한 옵션이 필요하다면 기능을 추가 구현 하면 될 것 같다.

 

NPM에도 올려놓았는데, 사용 중 ISSUE가 발생해서 리포팅이 들어왔으면 좋겠다....

 

https://www.npmjs.com/package/super-simple-circuit-breaker

 

super-simple-circuit-breaker

Super Simple Circuit Breaker

www.npmjs.com

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
class SimpleCircuitBreaker {
 
  /**
   * 
   * @param {Object} options 
   * @param {number} options.retry number of retry count
   * @param {number} opeions.halfopenTime open time in millesec
   */
  constructor(options) {
    this[STATUS] = CIRCUIT_STATUS.CLOSED
    this[OPTIONS] = options
    this[FAILED_COUNT] = 0
  }
 
  getCurrentStatus() {
    return this[STATUS]
  }
 
  run = async (func) => {
    const isAsync = func.constructor.name === "AsyncFunction";
    if(!isAsync) {
      return Promise.reject(new Error('Function must be async function'));
    }
 
    if(this[STATUS] === CIRCUIT_STATUS.OPEN) {
      return Promise.reject(new Error('CIRCUIT OPEN'));
    }
 
    return new Promise(async (resolve, reject) => {
      try {
        const result = await func();
        this.handleSuccess();
        resolve(result);
      } catch (err) {
        this.handleFail();
        reject(err);
      }
    })
  }
 
  handleFail = () => {
    this[FAILED_COUNT]++;
    if (this[FAILED_COUNT] >= 3) {
      this[STATUS] = CIRCUIT_STATUS.OPEN;
      this.startTimer();
    }
  }
 
  handleSuccess = () => {
    if (this[STATUS] === CIRCUIT_STATUS.CLOSED) return
    
    this.reset()
  }
 
  startTimer () {
    this[HALFOPEN_TIMER] = setTimeout(() => {
      this[STATUS] = CIRCUIT_STATUS.HALFOPEN
    }, this[OPTIONS].halfopenTime);
  }
 
  reset() {
    clearTimeout(this[HALFOPEN_TIMER]);
    this[STATUS] = CIRCUIT_STATUS.CLOSED;
    this[FAILED_COUNT] = 0;
  }
 
}
cs
반응형

+ Recent posts