27 January 2014
由於Node.js是Single thread的關係,
所以並不適合用來處理耗費CPU或者需要長時間處理的操作,
想要處理cpu-intensive或者long-running computation,
還是要靠一些job server來解決會比較好(像是gearman),
那如果你不想靠其他的job server來做,
硬要用node.js本身來處理cpu-intensive或者long-running computation,
就要靠worker來處理!
這篇就要講怎麼使用worker.
這裡我們要用的workder module是webworker-threads

1. install
npm install webworker-threads --save


2. implement a task.js

首先,我們要先建立一個javascript,
而這隻javascript就是用來處理需要長時間的操作,
這裡我們就以fibonacci來作為長時間處理的example,
// fibonacci function
function fibo (n){
return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}

onmessage = function(event) {
postMessage('Result is : ' + fibo(event.data));
self.close();
};

這隻javascript有兩個function,
一個是fibo function,
另外一個就是onmessage,onmessage等等我們主程式會call到它,
然後onmessage裡面就會去call fibo function.


3. integrate with your main.js

在這步就在你的main.js中使用webworker-threads,以及呼叫我們剛剛寫的那隻task.js,
var express = require("express");
var app = express();
app.use(express.logger());

// import the module
var worker_thread = require('webworker-threads');
var Worker = worker_thread.Worker;

app.use(express.static(path.join(__dirname, 'view')));

app.get('/fibo', function(req, resp) {

var worker = new Worker('task.js');

worker.onmessage = function(event) {
console.log("The task said : " + event.data);
};
worker.postMessage(40);

resp.end('hello world ');
});

var port = process.env.PORT || 5000;
app.listen(port, function() {
console.log("Listening on " + port);
});

這個example,一樣有使用到express.js,
不知道怎麼使用的人可以去看這一篇:Deploying a Node.js application to Heroku
webworker-threads的使用方式很簡單,
只要先import這個module,
然後再呼叫Worker這個instance,
接著就可以去new一個worker出來,
然後就可以指定要worker做什麼事情,
這裡我們指定他去做task.js裡面的事情(new worker('task.js')).

4. test

那要怎麼測試呢?
首先先把我們的main.js叫起來,
node main.js
成功叫起來以後,應該會在你的terminal中看到下面的字樣,


接著就打開我們的browser,
然後輸入“http://0.0.0.0:5000/fibo”,
這時候browser應該很快的就show出hello world的字樣,
然後我們馬上回到terminal看,
你應該只會先看到request的log(如下圖),


接著過了幾秒鐘以後才會看到fibo的計算結果(如下圖),


如果這裡我們沒有使用worker的話,而是直接call hibo,
你會發現很久才可以在browser中看到hello world的字樣!
且甚至你可以試試看開兩個browser,然後都去打“http://0.0.0.0:5000/fibo”,
你會發現第二個打的request會被hang住很久,因為是single thread的關係,
所以thread都在處理第一個request的fibo,處理完才會去處理第二個request!
因此想要在node.js中處理cpu-intensive或者long-running computation,
就使用worker的概念吧!





blog comments powered by Disqus