Inspired World

Node.js에서 진정한 Non-blocking 코드 구현, forAsync 모듈! 본문

Node.js

Node.js에서 진정한 Non-blocking 코드 구현, forAsync 모듈!

InspiredJW 2012.02.04 22:13
Node.js 에서의 장점은 non-blocking 입니다.

하지만 이것이 하기에 따라 오히려 독이 될 수도 있는데요.

blocking 코드를 Node.js 에서 작성하게 되면

Node.js 가 돌아가는 이벤트 루프의 특성상

모든 일이 blocking 코드가 다 할때까지 기다리게 됩니다.

예를 들어
 
for(var i=0; i<10000; i++) {    
    // Some heavy works
}
이와 같이 무거운 작업을 10000번을 한다고 하면

웹 어플리케이션 중간에 이런 부분이 있다면

다른 사람들의 작업은 물론 HTTP 요청마저 받아들이지 못하고

서버가 이 작업 하나 밖에 할 수 없기 때문에 서버가 멈춘 것처럼 되어버립니다.

그래서 이 방법을 해결할 수 있는 방법이

process.nextTick( callback );
process.nextTick 입니다.

사용하는 원리는 setTimeout 과 비슷하지만 setTimeout보다 벤치마킹 해보면

setTimeout result: 6156ms 
nextTick result: 196ms 

이렇게  나온다는 얘기가 있군요 ㅎㅎ

일반적으로 DB에서 뭉탱이(?) 를 가져와 하나씩 처리를 해줘야할 때가 있는데

이럴때는 forEach 같은 명령어를 써서 여러 데이터를 하나 하나씩 parsing 해줘야 합니다.

간단한 for loop 부터 forEach loop을 non-blocking 으로 구현한 모듈을 제가 하나 만들었습니다.

이 process.nextTick을 이용한건데요.

바로 forAsync 입니다! 

설치는 npm install forAsync 해주시고

var forAsync = require('forAsync');

이렇게 Node.js 소스 상단에 배치하면 사용가능합니다.


사용방법 또한 간단합니다!
 
//Upward Loop Function
forAsync.up( 0, 10, 1, function(i) {
    // Do something
}, function() {
    // callback
});

// Downward Loop Function
forAsync.down( 10, 1, 2, function(i) {
    // Do something
}, function() {
    // callback
});

// forEach Loop Function 
forAsync.forEach( Array, function(k, v) {
    // Do something
}, function() {
    // callback
});
보시는 바와 같이

up 은 

For Loop을 돌리면서 숫자가 커지는 경우 시작하는 숫자 0, 목표 10, 증가 숫자 1, 그리고

하고 싶은 일을 그 다음 함수에서 하시면 됩니다.

물론 i 값을 이용해서 반복되는 배열이나 객체에 접근할 수 있습니다.

down

up과 다른 점은 숫자가 큰 숫자에서 작은 숫자로 줄어드는 것 뿐입니다.

forEach

객체를 그대로 forEach 함수에 넣고 그 다음 함수에서 key, value  를 인자로 받아서

하고 싶은 일을 하실 수 있습니다.

마지막으로 이 세 함수 모두 다 콜백 함수를 가지고 있어서 이 함수가 작업을 마치고

하고 싶은 일은 콜백 함수 안에다가 정의해주시면 됩니다. 
8 Comments
  • 프로필사진 2012.02.17 20:01 비밀댓글입니다
  • 프로필사진 InspiredJW 2012.02.18 23:48 신고 네 저도 만들고 보니 비슷한게 이미 ^^;
  • 프로필사진 펌펌 2013.01.18 21:01 신고 퍼가도돼요?
  • 프로필사진 InspiredJW 2013.01.25 14:45 신고 네 ㅎㅎ

    근데 저도 요즘은

    caolan의 async.js 라이브러리를 쓰고 있어요

  • 프로필사진 꽃게장 2013.03.13 11:50 신고 안녕하세요.
    제가 node.js 를 이용해서 게시판을 만드는 중인데요
    파일업로드 시에 tmp 폴더에 담았다가 파일이 정상적으로 써지면 다시 upload 폴더에 옮기는 식으로 구현했습니다.
    그런데 여기서 파일을 옮기면서 파일의 이름을 이름+시간 으로 변경하면서 옮기거든요.
    그래서 function을 분리했는데 문제는 이 function 이 블로킹 io라는 점입니다.

    디비에 넣기전에 파일을 쓰고 옮겨야하기 때문에 블로킹이 됐는데 이부분도 node.js에서 좋지않은 구현이지 궁금합니다~

    무거운 작업은 아니라 상관없어 보이긴 하는데 node.js 의 특성?에 위배되는 행위라서 노파심에 한번 여쭤봅니다~
  • 프로필사진 InspiredJW 2013.03.15 23:04 신고 http://nodejs.org/api/child_process.html

    var spawn = require('child_process').spawn

    spawn을 이용해서 파일을 옮기세요.

    DB에 쓸 때에는 "이름 + 시간" 으로 등록하시면

    사실 상 파일을 옮기는 action과 DB에 기록하는 action이 parallel 하게 동작하면서

    좀 더 non-blocking 에 가깝게 되지 않을까요?
  • 프로필사진 꽃게장 2013.03.18 18:15 신고 답변 감사합니다^^

    말씀하신대로 parallel 하게 등록하면 예외상황에 대처하기 힘들지 않을까요??
    그래서 파일이 다 써진다음에 파일이름을 DB에 insert를 하도록 blocking function으로 구현했거든요 ㅎ

    var spawn = require('child_process').spawn 쪽을 더 봐봐야겠네요

    다시 한번 감사드립니다~~

    ps. 이제 zooqoos.com 은 닫힌건가요??


  • 프로필사진 InspiredJW 2013.03.22 13:46 신고 https://github.com/caolan/async

    async 모듈을 사용해보세요

    (주로 async.parallel, async.waterfall 로 flow control 합니다)

    error object를 적절히 활용하면 async IO 상황에서

    흐름이나 exception을 처리하기 훨씬 수월해집니다.

    그리고 zooqoos.com 은 곧 새롭게 오픈합니다 ^-^



댓글쓰기 폼