# 강남_P_Day15 리뷰 레포트 ### 참석자 - 고승빈, 김재호, 김웅기, 나영균 ## 1. 코드 동작 이해 ``` - 가장 많은 체크포인트를 구현한 사람의 코드의 동작 원리를 이해하는 과정에서 발생한 건설적인 대화를 기록, 정리합니다. ``` Event 기반으로 code 작성 ![Structure](https://user-images.githubusercontent.com/13862746/62669628-3dedb900-b9cb-11e9-8d97-cd732fd52619.jpg) Main에서 readline event 처음 발생 시 Manager Init 동작하여 Barista 인원 수 지정 다음 readline event 부터는 Cashier에 `order` Event 발생 Cashier에서 입력된 문자를 parser를 통해 재구성. 이 결과를 Waiting Table에 `add` Event 발생, Waiting Table에서는 OrderQueue를 새로 update 후 그 결과를 Manager 에서 `new` Event 발생한다. Manager에서는 `new` 발생시 Barista에 `exec` Event를 주는 동시 WaitingTable 과 DashBoard에 `update_making` Event 발생한다. Barista에서 작업이 끝난 후 `done` Event를 Manager에게 주면 Manager는 `update_done` Event를 WaintTable과 DashBoard에게 주고 Sync를 유지한다. Main Express는 DashBoard 에 정보를 가져와 web에 뿌려주는 역할을 한다. getTotal같은 경우는 전체 order_queue를 가져오고 getGuest는 특정 order_queue만 가지고 작업한다. ## 2. 코드 동작 개선 ``` - 다함께 하나 이상의 체크포인트를 구현하기 위해 시도했던 문제 해결의 과정을 정리합니다. - 학습정리의 `스스로 확인할 사항`에 대해 고민한 내용을 공유하고 서로의 코드를 더 발전시킬 수 있는 형태로 내용을 기록합니다. ``` ### Barista 개수 입력 처리 - Cashier 객체에서 모든 입력 처리를 하는 구조적인 문제 - Cafe 객체에서 객체간 의존을 주입하고 있는데, 해당 객체에서 바리스타 개수를 입력받아서 객체를 생성하면 될 것으로 보인다. ```javascript // Cafe 객체 // ... rl.setPrompt('바리스타 개수를 입력하세요: '); rl.prompt(); rl.on('line', (input) => { 바리스타 개수 = input }) // ... ``` ### Event Emitter 사용하지 않으며 동기적인 코드가 많은 문제 - 주문서의 모든 커피를 만들었다면, 아래와 같이 함수 호출로 계속 타고 올라간다. - 콜스택을 타고 올라가며 Event Emitter 보다 비효율적으로 동작한다. > Barista => Manager => Order => OrderQueue => Board ```javascript // Barista start() { // ... this.manager.completeOrder(); } // Manager completeOrder() { // ... order.transferCompleteEvent(); } // Order transferCompleteEvent() { // ... this.orderQueue.pushComplete(); } // OrderQueue pushComplete(order) { // ... // 현황판 업데이트 로직 // } ``` - Event Emitter 이용하면 **중간 함수 호출을 제거**할 수 있다. ```javascript // Barista start() { // ... emitter.emit('pushComplete'); } // OrderQueue pushComplete(order) { // ... emitter.on('pushComplete', () => { // 현황판 업데이트 로직 }); } ``` ### 고승빈 #### 스스로 확인할 사항 ##### Node.js 이벤트 루프와 이벤트 처리(Event Emitter) 방식에 대해 학습하고 정리한다. - Event Emitter를 통해 옵저버 패턴과 유사하게 Event를 등록한다. - Event Emitter는 emit() 함수를 제공하여, 해당하는 Event를 찾아서 EventHandler를 호출하는 기능을 제공한다. ##### Day14에서 워커를 사용한 멀티 스레드 방식과 단일 스레드에서 비동기 병렬 처리 방식에 대해 비교해서 학습하고 정리한다. - 멀티 스레드은 한정된 하드웨어 자원을 여러 스레드가 나눠서 사용하게 되지만, 병렬 처리는 동시에 많은 계산을 한꺼번에 처리가 가능하다. - 멀티 스레드 방식은 스케줄링 알고리즘이 필요하다. - 비동기 로직을 병렬 처리하며 멀티 스레드 방식보다 나은 성능을 발휘할 수 있다. --- ### 김재호 #### 스스로 확인할 사항 - Node.js 이벤트 루프와 이벤트 처리(Event Emitter) 방식에 대해 학습하고 정리한다. emit의 경우 Sync로 동작한다. 따라서 Emitter의 경우 긴 작업이 생길때 다른 작업을 하지 못하고 Sync로 처리하여 병렬처리가 될 수 없다. 하지만 Event Loop의 경우는 Async로 동작하여, Call Stack이 비어지고 event queue를 보아서 동작한다. 따라서 여러가지 일을 병렬처리 될 수 있다. - Day14에서 워커를 사용한 멀티 스레드 방식과 단일 스레드에서 비동기 병렬 처리 방식에 대해 비교해서 학습하고 정리한다. MultiThread 방식은 동시에 여러가지 일을 처리할 수 있다는 점에서 장점을 지닌다. 하지만 CriticalSection에 접근하는 일의 경우 data의 무결성을 보장할 수 없다. 반대로 SingleThread 비동기 병렬처리의 경우 일을 한번에 하나만 동작하여 data의 무결성을 보장받지만, 동작이 너무 느리다는 단점이 있다. --- ### 김웅기 #### 스스로 확인할 사항 ##### Node.js 이벤트 루프와 이벤트 처리(Event Emitter) 방식에 대해 학습하고 정리한다. - 이벤트 루프는 가능하다면 언제나 시스템 커널에 작업을 떠넘겨서 Node.js가 논 블로킹 I/O 작업을 수행하도록 해준다. - 이벤트 루프의 각 단계 - timers: 이 단계는 setTimeout()과 setInterval()로 스케줄링한 콜백을 실행. - pending callbacks: 다음 루프 반복으로 연기된 I/O 콜백들을 실행. - idle, prepare: 내부용으로만 사용. - poll: 새로운 I/O 이벤트를 가져온다. I/O와 연관된 콜백(클로즈 콜백, 타이머로 스케줄링된 콜백, setImmediate()를 제외한 거의 모든 콜백)을 실행. 적절한 시기에 node는 여기서 블록 합니다. - check: setImmediate() 콜백은 여기서 호출된다. - close callbacks: 일부 close 콜백들, 예를 들어 socket.on('close', ...). - Event Emitter는 Observer처럼 이벤트를 가지고 있다가 등록된 이벤트가 발생하면 미리 지정된 콜백을 콜스택에 집어넣는다. - 레퍼런스: https://nodejs.org/ko/docs/guides/event-loop-timers-and-nexttick/ ##### Day14에서 워커를 사용한 멀티 스레드 방식과 단일 스레드에서 비동기 병렬 처리 방식에 대해 비교해서 학습하고 정리한다. - 멀티 스레드는 다시 말하면 콜 스택이 여러개가 있는 형태이다. 따라서 여러개의 작업을 동시에 실행할 수 있다. 비동기 병렬 처리 방식은 여러개의 작업을 동시에 가지고 대기를 시킨 후에 순서대로 콜 스택에 밀어넣는 일을 하기 때문에 결국 하나의 콜 스택이 모든 일을 처리하게 된다. 예를 들어 메인 콜 스택에 들어있는 함수의 실행에 10초가 소요되고, 다음 콜백이 timer 5초가 걸려있다고 한다면 콜백 함수는 5초가 지나도 실행될 수 없을 것이다. 그러나 멀티 스레드에서는 별도의 스택에서 실행되기 때문에 5초가 지나면 실행될 수 있다. --- ### 나영균