GitXplorerGitXplorer
z

node-fork

public
16 stars
2 forks
0 issues

Commits

List of commits on branch master.
Unverified
b9b3923406ed9d43545932bb301e96a1746e8366

Merge pull request #1 from masylum/patch-1

zzcbenz committed 13 years ago
Unverified
ea5e2a408ecf175f5a586e2d454529ea03f8e95a

You don't have to write spagetti if you don't want.

mmasylum committed 13 years ago
Unverified
cef628066e929c5ebfa3bbdc0b1a34e237f7e1f7

Add a new example

zzcbenz committed 13 years ago
Unverified
ef2b6282bc6874c0acd7f2b5c185d4d1b86378ea

Add LICENSE

zzcbenz committed 13 years ago
Unverified
8354d7f0464c3273ec7d491fae3298d8b8ae40cc

Add a `Process` class

zzcbenz committed 13 years ago
Unverified
3723edb8334f7e6aed8d13be9a5f45fb542488f4

Catches exceptions in `call`

zzcbenz committed 13 years ago

README

The README file for this repository.

node-fork

In short, node-fork makes a synchronous function asynchronous.

In longer words, node-fork makes uses of fork system call to provide concurrency ability to the node.js, it can make a synchronous function really-asynchronous, thus completely get rid of the nested asynchronous calls.

And if you're interested, the interface emulates C++0x's thread library.

At a glance

calculate_the_answer_to_LtUaE.js

var sleep  = require("../fork").sleep;
var future = require("../fork").future;

function calculate_the_answer_to_LtUaE () {
    sleep (5);

    return 42;
}

var answer = future (calculate_the_answer_to_LtUaE);

console.log ("blablabla...");

console.log ("The answer to life, the universe and everything is",
             answer.get ());

propagate.js

var fork = require("../fork").fork;

for (var i = 0; i < 5; i++) {
    fork ();

    console.log (i);
};

lots_of_websites.js

// You will need node-curl to gain synchorous http ability
// at https://github.com/zcbenz/node-curl

var curl   = require("../node_curl");
var sleep  = require("../fork").sleep;
var async  = require("../fork").async;

console.log ("I'm visiting websites in 4 processes!");

async (function () {
    console.log ("sina");
    curl.get ("http://sina.com").end();
    console.log ("baidu");
    curl.get ("http://baidu.com").end();
    console.log ("weibo");
    curl.get ("http://weibo.com").end();
    console.log ("163");
    curl.get ("http://163.com").end();
    console.log ("sohu");
    curl.get ("http://sohu.com").end();
    console.log ("cnbeta");
    var res = curl.get ("http://cnbeta.com").end();

    return res.headers;
}, function (result) {
    console.log ("headers of cnbeta is:", result);
});

async (function () {
    console.log ("sohu");
    return curl.get ("http://sohu.com").end ().headers;
}, function (result) {
    console.log ("headers of sohu is:", result);
});

async (function () {
    console.log ("163");
    return curl.get ("http://163.com").end ().headers;
}, function (result) {
    console.log ("headers of 163 is:", result);
});

async (function () {
    console.log ("douban");
    curl.get ("http://douban.com").end ().headers;
    console.log ("taobao");
    return curl.get ("http://taobao.com").end ().headers;
}, function (result) {
    console.log ("headers of taobao is:", result);
});

// Just to block the main process
require("http").createServer(function (req, res) {
}).listen(9001);

sleeping_pigs.js

var sleep = require("../fork").sleep;
var async = require("../fork").async;

for (var i = 0; i < 10; ++i) {
    async (function () {
        sleep (i);
        console.warn ("Pig " + i + " awakes!");
    });
}

// Just to block the main process
require("http").createServer(function (req, res) {
}).listen(9001);

Why this when already have asynchronous calls in node

In node days, if we want a chain of asynchronous calls, we would end up with something like this:

function onFileD(err) {
  console.log ("finally", data);
}

function onFileC(err, data) {
  data += "blabla";
  fs.writeFile ("d", data, onFileD);
}
 
function onFileB(err) {
 fs.readFile ("c", onFileC);
}

function onFileA(err, data) {
  data += "blabla";
  fs.writeFile ("b", data, onFileB);
}

fs.readFile ("a", onFileA);

But with node-fork, we can use the synchronous functions just like the good old days:

async (function () {
    fs.writeFileSync ("b", fs.readFileSync ("a") + "blabla");
    data = fs.readFileSync ("d") + "blabla";
    fs.writeFileSync ("d", data);

    return data;
}, function (data) {
    console.log ("finally", data);
});

Build

Just simply make.

APIs

future (call)

future() will invoke the call function in a new process by calling fork(). The call function will have the exact state with the parent process.

The return value of future() has a method get(), get() will return the return value of call function. If call has not ended when get() is called, the calling process of get() will wait until the call ends.

Example

function calculate_the_answer_to_LtUaE () {
    sleep (5);

    return 42;
}

var answer = future (calculate_the_answer_to_LtUaE);

console.log ("blablabla...");

console.log ("The answer to life, the universe and everything is",
             answer.get ());

async (call, [back])

async() will invoke the call function in a new process by calling fork(). The call function will have the exact state with the parent process.

After the call function ended, the back function will be invoked, the return value of call function will be passed as a parameter in the back.

Example:

async (function () {
    sleep (5);
    return 42;
}, function (result) {
    console.log ("The answer to life, the universe and everything is",
                 result);
});

sleep (seconds)

Same with man 3 sleep.

sleep() makes the calling process sleep until seconds seconds have elapsed. sleep() will ignore signals.

fork ()

Same with man 2 fork.

fork() creates a new process by duplicating the calling process. The new process, referred to as the child, is an exact duplicate of the calling process, referred to as the parent.

The PID of the child process is returned in the parent, and 0 is returned in the child.

BUG

The project is not done yet, it has bugs and no unit tests, and it will crash when call throws exceptions...

And node-curl uses processes instead of threads to invoke the call, it will be a bit resource-consuming, this is because v8 engine does not support threads good enough. When v8 finally supports threads, I will make an equivalent threading one.

License

All codes are published under MIT license.