Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could one write a native Node.js extension in Go, as opposed to C++?

That's all there is to my question, really, but I think it's an interesting thing to have answered.

like image 590
user3025492 Avatar asked Dec 22 '13 10:12

user3025492


People also ask

Should I use Go or NodeJS?

Out of the gate, Go beats Node. js in terms of scalability because it supports concurrency, which helps handle side-by-side tasks. Go can manage 1000 concurrent requests per second, making Go superior.

Is Golang similar to NodeJS?

Golang is a statically typed garbage-collected programming language enabling high performance, while NodeJS is a cross-platform runtime environment (not a language or a framework). So to say, while Go functions by itself, NodeJS actually helps JavaScript to function as a server-side language.

Is NodeJS faster than C?

c to use a double instead of a long in the loop, the time C took was even longer! Not trying to start a flame war, but why is Node. JS (116 ms.) so much faster than native C (198 ms.)

Why do we need C++ addons in NodeJS?

It gives the opportunity to make intensive, parallel, and high-accuracy calculations. It also gives the opportunity to use C++ libraries in NodeJS. We can integrate a third-party library written in C/C++ and use it directly in NodeJS.


2 Answers

With the addition of support for shared libraries in go, this is possible now.

calculator.go:

// package name: calculator package main  import "C"  //export Sum func Sum(x, y float64) float64 {     return x + y }  func main() { } 

node-calculator.cc:

#include "calculator.h" #include <node.h>  namespace calc {    using v8::FunctionCallbackInfo;   using v8::Isolate;   using v8::Local;   using v8::Object;   using v8::String;   using v8::Value;   using v8::Number;   using v8::Exception;    void add(const FunctionCallbackInfo<Value>& args) {     Isolate* isolate = args.GetIsolate();      // Check the number of arguments passed.     if (args.Length() < 2) {       // Throw an Error that is passed back to JavaScript       isolate->ThrowException(Exception::TypeError(           String::NewFromUtf8(isolate, "Wrong number of arguments")));       return;     }      // Check the argument types     if (!args[0]->IsNumber() || !args[1]->IsNumber()) {       isolate->ThrowException(Exception::TypeError(           String::NewFromUtf8(isolate, "Wrong arguments")));       return;     }      // Perform the operation     Local<Number> num = Number::New(isolate, Sum(args[0]->NumberValue(), args[1]->NumberValue()));      // Set the return value (using the passed in     // FunctionCallbackInfo<Value>&)     args.GetReturnValue().Set(num);   }    void init(Local<Object> exports) {     NODE_SET_METHOD(exports, "add", add);   }    NODE_MODULE(calculator, init) } 

binding.gyp:

{   "targets": [     {       "target_name": "node-calculator",       "sources": [         "node-calculator.cc"       ],       "libraries": [         "../calculator.a"       ],     },   ], } 

test.js:

const calculator = require('./build/Release/node-calculator'); console.log('4+5=', calculator.add(4, 5)); 

Build:

go build -buildmode c-archive -o calculator.a calculator.go node-gyp configure node-gyp build 

Output:

#> node test.js  4+5= 9 
like image 88
kraman Avatar answered Sep 22 '22 19:09

kraman


Native module for node.js must deeply interact with V8 process which contains a lot of v8 concepts such as gc, javascript context, ...

And I don't think V8 has exposed compatible and stable APIs for other language to interact with it. That is why node.js native addon should be built with C++ and always imports V8 C++ headers.


But you can use GO to write node.js native addons by wrapping GO code with C++:

file: module.go

package main  func Add(a, b int) int {     return a + b } 

file: module.c

#include <node.h> #include <v8.h>  using namespace v8;  extern int go_add(int, int) __asm__ ("example.main.Add");  void init(Handle<Object> exports) {     // call go_add }  NODE_MODULE(module, init) 

More about "how to call GO functionn from C/C++":

Call Go functions from C


Edit:

Please see @jdi comments and the link: https://groups.google.com/forum/#!msg/golang-nuts/FzPbOwbTlPs/dAJVWQHx6m4J

Quote: It might be doable for simple things like add (that don't generate garbage or require the runtime), but it's not supported (yet) by either compiler as far as I know. Part of the work is done for linux (see golang.org/issue/256), but there are a number of open questions (what happens when you load two shared objects? etc)

like image 26
damphat Avatar answered Sep 19 '22 19:09

damphat