microsoft / napajs

Napa.js: a multi-threaded JavaScript runtime

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: Passing buffer as an argument works

nveenjain opened this issue · comments

Hey everyone, First of all thanks for this awesome runtime, I've been tinkering with napajs, and got to know that Buffer is not transportable, but when i tried to run following code, it runs as expected, Could you please clarify, why? Is this hack allowed, so we could in theory pass any object and napa would not throw any error?

var napa = require('napajs');
var zone1 = napa.zone.create('zone1', { workers: 4 });
var x = (Buffer.from("napajs is awesome","utf8"));
zone1.execute((x)=>{
    console.log(JSON.stringify(String.fromCharCode.apply(null,new Uint8Array(x.data))));
},[x]);

Also, if I want to implement a Transportable class without using decorators, it isn't working.
I'm implementing using:-

class z extends napa.transport.TransportableObject{
...
};
napa.transport.register(z);

It throws error that Class "z" doesn't implement cid(), did you forget put @cid decorator before class declaration? Please help, Thanks!

Hi @nveenjain , currently Buffer is not supported by Napa.js (https://github.com/Microsoft/napajs/blob/master/docs/api/transport.md#--transportable-types). This is because Buffer is a built-in Node.js type -- it's not only a type that used to access data in bytes (as Uint8Array), but also has functions like read and write, which highly depends on Node.js's native stream implementation and libuv. To transport a Buffer object and use those I/O functions in another javascript thread will cause undefined behavior.

However, if you just want to transport the data in a Buffer for readonly-purpose(ie. access the buffer as a byte array), there is way to do that. Javascript built-in types such as ArrayBuffer and Uint8Array is transportable in Napa.js:

var napa = require('napajs');
var zone1 = napa.zone.create('zone1', { workers: 4 });
var buf = (Buffer.from("napajs is awesome","utf8"));
var byteArray = new Uint8Array(buf.buffer, buf.offset, buf.length);
zone1.execute((x) => {
    console.log(x);
}, [byteArray]);
// output: 110,97,112,97,106,115,32,105,115,32,97,119,101,115,111,109,101

Thanks a lot.

@fs-eire maybe it's better to document this workaround, until Buffer is supported?

I see in the project tab of project, that you guys are improving node API, what could be the possible timeline after which we can transport buffer too? Thanks for all your work. Also I would love to document this workaround, if you say.