Channels for javascript concurrency pattern
npm install co-channelThree cases are investigated.
- [Case I: Heavy calculation processes without IO blocking]
- [Case II: Heavy calculation processes with IO blocking]
- [Case III: Light calculation processes with IO blocking]
[Case I: Heavy calculation processes without IO blocking]:
[Case II: Heavy calculation processes with IO blocking]:
[Case III: Light calculation processes with IO blocking]:
To-conclude: Coroutine has compatible performance with goroutine when the routines are lightweight computation with heavy IO blocking where is most the cases in real life.
javascript
var co = require('co');
var channel = require('co-channel');
`
`javascript
// Communicating sequential processes
// Each process is considered as executing independently and communicated via co-channel
// Process 1 initilize a data brick, pass to process 2 via channel-1
// Process 2 reveive data via channel-1, and pass to process 3 via channel-2
// Process 3 receive data via channel-2, and pass back to process 1 via channel-1
// Process 1 wait until data received from process 3 and print the data out
var ch1 = new channel();
var ch2 = new channel();
var ch3 = new channel();
// Process 1
co(function*(){
var data = '0';
yield ch1.put(data);
data = yield ch3.take();
console.log(data);
})
// Process 2
co(function*(){
var data = ch1.take();
data += '-1';
ch2.put(data);
})
// Process 3
co(function*(){
var data = ch2.take();
data += '-2';
ch3.put(data)
})
`
`javascript
// selecting the channel which is available first
var sequence = '';
var ch1 = new channel();
var ch2 = new channel();co(function*(){
var brick = yield channel.select([
ch1.take.selected(),
ch2.take.selected()
]);
console.log('brick from channel 2 is token', brick);
})
ch2.put(2).then(_ => sequence += 2);
ch1.put(1).then( _=> sequence += 1);
`
`javascript
// Scrapper
// Another milestone of co-channel is to allow co-routine scrapping
// co-channel allow wrapping a promise to limit the number of co-occurrence
var download = function(url){
return new Promise((resolve, reject) => {
http.get(url, function(response){
response.setEncoding('utf8');
var data = '';
response.on('data', function(chunk){
data += chunk;
})
response.on('end', function(){
resolve(data);
})
})
.on('error', function(err){
reject(err);
})
})
}
var downloadCo = channel.wrap(download); // wrapping a http-download promise
var ch = new channel(2); // limiting the co-occurrence be 2downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
downloadCo('http://www.example.com/', ch).then(_ => console.log(i++)).catch(err => console.log(err))
// Those http requests are queued and doing max 2 http request in the same time
`` [new channel(buffer_no, type='default')]:
[channel.put(brick)]:
[channel.take()]:
[channel.close()]:
[channel.stake()]:
[channel.sput(brick)]:
[channel.select(selectedArr)]:
[channel.take.selected()]:
[channel.put.selected()]:
[channel.wrap()]:
[channel.DEFAULT]:
[channel.SLIDING]:
[channel.DROPING]: