11

I´m searching for a way to build c++ modules for NodeJs with the current release (0.5.9). By using the following tutorial and abstracting from nodes node_file.cc I was able to build a module by my self for node 0.5.3.

But with node 0.5.4 some of the API´s must have changed because because I´m no longer able to warp functions with eio_* anymore.

Looking at node_file.cc I discovered that the eio_* wrapping is replaced by new ReqWrap classes.

For Example in this macro: https://gist.github.com/1303926

No I wonder what's the best way of writing async extensions?

1 Answer 1

15

Basically looking at the crypto node module solved my problem this module was not poluted with macros like the file module. I came up with a simple async module that calculates the sum of two integers:

#include <v8.h>
#include <node.h>
#include <stdlib.h>
#include <errno.h>

using namespace node;
using namespace v8;

struct Test_req
{
    ssize_t result;
    ssize_t int1;
    ssize_t int2;
    Persistent<Function> callback;
};

void TestWorker(uv_work_t* req)
{
    Test_req* request = (Test_req*)req->data;
    request->result = request->int1 + request->int2;
}

void TestAfter(uv_work_t* req)
{
    HandleScope scope;

    Test_req* request = (Test_req*)req->data;
    delete req;

    Handle<Value> argv[2];

        // XXX: Error handling
    argv[0] = Undefined();
    argv[1] = Integer::New(request->result);

    TryCatch try_catch;

    request->callback->Call(Context::GetCurrent()->Global(), 2, argv);

    if (try_catch.HasCaught()) 
    {
        FatalException(try_catch);
    }

    request->callback.Dispose();

    delete request;
}


static Handle<Value> Test(const Arguments& args)
{

    HandleScope scope;

    if ( args.Length() < 3 || !args[0]->IsNumber() || !args[1]->IsNumber() )
    {
        return ThrowException(Exception::TypeError(String::New("Bad argument")));
    }

    ssize_t int1 ( args[0]->Int32Value() );
    ssize_t int2 ( args[1]->Int32Value() );

    if ( args[2]->IsFunction() )
    {
        Local<Function> callback = Local<Function>::Cast(args[2]);

        Test_req* request = new Test_req;
        request->callback = Persistent<Function>::New(callback);

        request->int1 = int1;
        request->int2 = int2;

        uv_work_t* req = new uv_work_t();
        req->data = request;

        uv_queue_work(uv_default_loop(), req, TestWorker, TestAfter);
    }
    else
    {
        return ThrowException(Exception::TypeError(String::New("Callback missing")));
    }

    return Undefined();
}

extern "C"
{
    static void init(Handle<Object> target)
    {
        HandleScope scope;
    }
}
NODE_MODULE(node_AsyncTest, init);

On the node side you call the module like this:

var foo = process.binding('AsyncTest');

foo.Test(1,2,function(err,data){
  console.log(err,data);
});

result:

undefined 3

Hope this is helpful ;)

Ps: Since the lack of node compiling extensions under windows. I´m building this directly into the core of the node windows port with the Visual Studio build solution.

Sign up to request clarification or add additional context in comments.

1 Comment

So, Can we implement our own async modules for performing complex computations? Will that help us from blocking node thread?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.