반응형

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
반응형
반응형

설명

RGB거리에 사는 사람들은 집을 빨강, 초록, 파랑중에 하나로 칠하려고 한다. 또한, 그들은 모든 이웃은 같은 색으로 칠할 수 없다는 규칙도 정했다. 집 i의 이웃은 집 i-1과 집 i+1이다.

각 집을 빨강으로 칠할 때 드는 비용, 초록으로 칠할 때 드는 비용, 파랑으로 드는 비용이 주어질 때, 모든 집을 칠할 때 드는 비용의 최솟값을 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 집의 수 N이 주어진다. N은 1,000보다 작거나 같다. 둘째 줄부터 N개의 줄에 각 집을 빨강으로 칠할 때, 초록으로 칠할 때, 파랑으로 칠할 때 드는 비용이 주어진다. 비용은 1,000보다 작거나 같은 자연수이다.

 

해설

 아래와 같이 집1, 집2, 집3인 경우의 R,G,B 페인트를 칠하는 비용이 있다고 가정한다.

Dynamic programming은 이전 계산값을 저장해서 다음 계산에 사용한다고 생각할 수 있다.

아래 그림을 보면 위에서 만든 자료구조를 가지고 같은 모양(열과 행이 같은) 자료구조를 만들어 자료를 업데이트 하는 것을 볼 수 있다.

업데이트를 하는 과정은 아래와 같다.

1. 각 샐은 현재 집을 해당 컬럼(R,G,B)로 칠했을때의 최소 비용이다.

2. 집2에 빨간색을 칠하는 경우 : 집2를 빨간색으로 칠하는 비용 + 최소값(집1을 초록색으로 칠하는 경우, 집 1을 파란색으로 칠하는 경우)

    집2에 파란색을 칠하는 경우 : 집2를 파란색으로 칠하는 비용 + 최소값(집1을 초록색으로 칠하는 경우, 집 1을 빨간으로 칠하는 경우)

위 2개의 규칙을 따라서 전체 셀을 업데이트 한다.

마지막까지의 최소비용을 구하면 해당 row에서 가장 최소인 값을 출력해주면된다.

 

코드

 

 

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
var fs = require('fs');
var input = fs.readFileSync('/dev/stdin').toString().split('\n');
 
// 입력값을 2중 배열로 저장해놓는다.
var numberOfHouses = parseInt(input[0]);
const costsForPainting = []
for(let i = 1; i <= numberOfHouses; i++) {
  costsForPainting.push(input[i].split(" ").map(el => parseInt(el)))
}
 
// 최솟값을 이용하여 계산하는 부분이 많이 때문에 최솟값을 구하는 함수를 미리 짜둔다
function min(list) {
  let min
  for(const num of list) {
    if(!min) {
      min = num
      continue
    }
    if(num < min) min = num
  }
  return min
}
 
// 그림에서 설명한것과 같이 2중 list를 만들어야 한다.
const minCostForPainting = []
for(let i = 0; i < numberOfHouses; i++) {
  // 첫번째 집에 경우 기존 입력값을 그대로 사용한다.
  if(i === 0) {
    minCostForPainting.push(costsForPainting[0])
    continue
  }
 
  // 현재 집(i)를 생상별로 칠할때의 최소 비용을 구한다.
  // 현재 집을 Red로 칠하는 경우 = 현재집을 red로 칠하는 비용 + 이전집을 green blue로 칠할때 비용 중 최소값.
  const currentHouseRedCost = costsForPainting[i][0+ min([minCostForPainting[i-1][1], minCostForPainting[i-1][2]])
  const currentHouseGreenCost = costsForPainting[i][1+ min([minCostForPainting[i-1][0], minCostForPainting[i-1][2]])
  const currentHouseBlueCost = costsForPainting[i][2+ min([minCostForPainting[i-1][0], minCostForPainting[i-1][1]])
 
  const currentMinCost = [currentHouseRedCost, currentHouseGreenCost, currentHouseBlueCost]
  minCostForPainting.push(currentMinCost)
}
console.log(min(minCostForPainting[minCostForPainting.length - 1]))
cs
반응형
반응형

문제

세 점이 주어졌을 때, 축에 평행한 직사각형을 만들기 위해서 필요한 네 번째 점을 찾는 프로그램을 작성하시오.

입력

세 점의 좌표가 한 줄에 하나씩 주어진다. 좌표는 1보다 크거나 같고, 1000보다 작거나 같은 정수이다.

출력

직사각형의 네 번째 점의 좌표를 출력한다.

해설

축에 평행한 직사각형을 만들기 위해서는 사실 두개의 점만 알고 있다면 직사각형을 그릴 수 있다.

 

직사각형의 시작점과 끝점 2개(그림에서 파란색 점 두개)만 안다면 직사각형을 그릴 수 있다.

 

(x1, y1) (x2,y2) 두개의 점을 안다고 하는 경우 아래와 같이 직사각형이 그려진다.

 

다시 문제로 넘어가면, 3개의 점을 알고 있다면 x1, y1, x2, y2 4개의 값을 모두 알 수 있다.

 

점 4개의 좌표값을 모으면 각자 2번씩 등장하기 때문에 우리는

 

3개의 점의 좌표값 중 1번만 등장하는 값을 찾으면 된다.

코드

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
var fs = require('fs');
var lines = fs.readFileSync('/dev/stdin').toString().split('\n');
var points = lines.map(lines => {
  const points = lines.split(" ").map(el => parseInt(el));
  return points
})
 
const xList = []
const yList = []
 
for(let point of points) {
  const xIndex = xList.findIndex(el => el === point[0])
  if(xIndex != -1) {
    xList.splice(xIndex, 1)
  } else {
    xList.push(point[0])
  }
 
  const yIndex = yList.findIndex(el => el === point[1])
  if(yIndex != -1) {
    yList.splice(yIndex, 1)
  } else {
    yList.push(point[1])
  }
}
 
console.log(`${xList[0]} ${yList[0]}`)
 
 
cs

 

 

반응형

+ Recent posts