forked from nodejs/abi-stable-node-addon-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Porting asynchronous example from NAN repo
The original example is hosted here: https://github.com/nodejs/nan/tree/master/examples/async_pi_estimate Rewrite all the logic using **node-addon-api** See the following issue https://github.com/nodejs/abi-stable-node-addon-examples/issues/10
- Loading branch information
Showing
22 changed files
with
477 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
In this directory run `node-gyp rebuild` and then `node ./addon.js` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#include <nan.h> | ||
#include "sync.h" // NOLINT(build/include) | ||
#include "async.h" // NOLINT(build/include) | ||
|
||
using v8::FunctionTemplate; | ||
using v8::Handle; | ||
using v8::Object; | ||
using v8::String; | ||
using Nan::GetFunction; | ||
using Nan::New; | ||
using Nan::Set; | ||
|
||
// Expose synchronous and asynchronous access to our | ||
// Estimate() function | ||
NAN_MODULE_INIT(InitAll) { | ||
Set(target, New<String>("calculateSync").ToLocalChecked(), | ||
GetFunction(New<FunctionTemplate>(CalculateSync)).ToLocalChecked()); | ||
|
||
Set(target, New<String>("calculateAsync").ToLocalChecked(), | ||
GetFunction(New<FunctionTemplate>(CalculateAsync)).ToLocalChecked()); | ||
} | ||
|
||
NODE_MODULE(addon, InitAll) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
var addon = require('./build/Release/addon'); | ||
var calculations = process.argv[2] || 100000000; | ||
|
||
function printResult(type, pi, ms) { | ||
console.log(type, 'method:'); | ||
console.log('\tπ ≈ ' + pi + | ||
' (' + Math.abs(pi - Math.PI) + ' away from actual)'); | ||
console.log('\tTook ' + ms + 'ms'); | ||
console.log(); | ||
} | ||
|
||
function runSync() { | ||
var start = Date.now(); | ||
// Estimate() will execute in the current thread, | ||
// the next line won't return until it is finished | ||
var result = addon.calculateSync(calculations); | ||
printResult('Sync', result, Date.now() - start); | ||
} | ||
|
||
function runAsync() { | ||
// how many batches should we split the work in to? | ||
var batches = process.argv[3] || 16; | ||
var ended = 0; | ||
var total = 0; | ||
var start = Date.now(); | ||
|
||
function done (err, result) { | ||
total += result; | ||
|
||
// have all the batches finished executing? | ||
if (++ended === batches) { | ||
printResult('Async', total / batches, Date.now() - start); | ||
} | ||
} | ||
|
||
// for each batch of work, request an async Estimate() for | ||
// a portion of the total number of calculations | ||
for (var i = 0; i < batches; i++) { | ||
addon.calculateAsync(calculations / batches, done); | ||
} | ||
} | ||
|
||
runSync(); | ||
runAsync(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#include <nan.h> | ||
#include "pi_est.h" // NOLINT(build/include) | ||
#include "async.h" // NOLINT(build/include) | ||
|
||
using v8::Function; | ||
using v8::Local; | ||
using v8::Number; | ||
using v8::Value; | ||
using Nan::AsyncQueueWorker; | ||
using Nan::AsyncWorker; | ||
using Nan::Callback; | ||
using Nan::HandleScope; | ||
using Nan::New; | ||
using Nan::Null; | ||
using Nan::To; | ||
|
||
class PiWorker : public AsyncWorker { | ||
public: | ||
PiWorker(Callback *callback, int points) | ||
: AsyncWorker(callback), points(points), estimate(0) {} | ||
~PiWorker() {} | ||
|
||
// Executed inside the worker-thread. | ||
// It is not safe to access V8, or V8 data structures | ||
// here, so everything we need for input and output | ||
// should go on `this`. | ||
void Execute () { | ||
estimate = Estimate(points); | ||
} | ||
|
||
// Executed when the async work is complete | ||
// this function will be run inside the main event loop | ||
// so it is safe to use V8 again | ||
void HandleOKCallback () { | ||
HandleScope scope; | ||
|
||
Local<Value> argv[] = { | ||
Null() | ||
, New<Number>(estimate) | ||
}; | ||
|
||
callback->Call(2, argv, async_resource); | ||
} | ||
|
||
private: | ||
int points; | ||
double estimate; | ||
}; | ||
|
||
// Asynchronous access to the `Estimate()` function | ||
NAN_METHOD(CalculateAsync) { | ||
int points = To<int>(info[0]).FromJust(); | ||
Callback *callback = new Callback(To<Function>(info[1]).ToLocalChecked()); | ||
|
||
AsyncQueueWorker(new PiWorker(callback, points)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef EXAMPLES_ASYNC_PI_ESTIMATE_ASYNC_H_ | ||
#define EXAMPLES_ASYNC_PI_ESTIMATE_ASYNC_H_ | ||
|
||
#include <nan.h> | ||
|
||
NAN_METHOD(CalculateAsync); | ||
|
||
#endif // EXAMPLES_ASYNC_PI_ESTIMATE_ASYNC_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"targets": [ | ||
{ | ||
"target_name": "addon", | ||
"sources": [ | ||
"addon.cc", | ||
"pi_est.cc", | ||
"sync.cc", | ||
"async.cc" | ||
], | ||
"include_dirs": ["<!(node -e \"require('nan')\")"] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "async_work", | ||
"version": "0.0.0", | ||
"description": "Node.js Addons Example #9", | ||
"main": "addon.js", | ||
"private": true, | ||
"gypfile": true, | ||
"dependencies": { | ||
"nan": "*" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#include <cstdlib> | ||
#include "pi_est.h" // NOLINT(build/include) | ||
|
||
/* | ||
Estimate the value of π by using a Monte Carlo method. | ||
Take `points` samples of random x and y values on a | ||
[0,1][0,1] plane. Calculating the length of the diagonal | ||
tells us whether the point lies inside, or outside a | ||
quarter circle running from 0,1 to 1,0. The ratio of the | ||
number of points inside to outside gives us an | ||
approximation of π/4. | ||
See https://en.wikipedia.org/wiki/File:Pi_30K.gif | ||
for a visualization of how this works. | ||
*/ | ||
|
||
inline int randall(unsigned int *p_seed) { | ||
// windows has thread safe rand() | ||
#ifdef _WIN32 | ||
return rand(); // NOLINT(runtime/threadsafe_fn) | ||
#else | ||
return rand_r(p_seed); | ||
#endif | ||
} | ||
|
||
double Estimate (int points) { | ||
int i = points; | ||
int inside = 0; | ||
unsigned int randseed = 1; | ||
|
||
#ifdef _WIN32 | ||
srand(randseed); | ||
#endif | ||
|
||
// unique seed for each run, for threaded use | ||
unsigned int seed = randall(&randseed); | ||
|
||
#ifdef _WIN32 | ||
srand(seed); | ||
#endif | ||
|
||
while (i-- > 0) { | ||
double x = randall(&seed) / static_cast<double>(RAND_MAX); | ||
double y = randall(&seed) / static_cast<double>(RAND_MAX); | ||
|
||
// x & y and now values between 0 and 1 | ||
// now do a pythagorean diagonal calculation | ||
// `1` represents our 1/4 circle | ||
if ((x * x) + (y * y) <= 1) | ||
inside++; | ||
} | ||
|
||
// calculate ratio and multiply by 4 for π | ||
return (inside / static_cast<double>(points)) * 4; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef EXAMPLES_ASYNC_PI_ESTIMATE_PI_EST_H_ | ||
#define EXAMPLES_ASYNC_PI_ESTIMATE_PI_EST_H_ | ||
|
||
double Estimate(int points); | ||
|
||
#endif // EXAMPLES_ASYNC_PI_ESTIMATE_PI_EST_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <nan.h> | ||
#include "pi_est.h" // NOLINT(build/include) | ||
#include "sync.h" // NOLINT(build/include) | ||
|
||
// Simple synchronous access to the `Estimate()` function | ||
NAN_METHOD(CalculateSync) { | ||
// expect a number as the first argument | ||
int points = info[0]->Uint32Value(); | ||
double est = Estimate(points); | ||
|
||
info.GetReturnValue().Set(est); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef EXAMPLES_ASYNC_PI_ESTIMATE_SYNC_H_ | ||
#define EXAMPLES_ASYNC_PI_ESTIMATE_SYNC_H_ | ||
|
||
#include <nan.h> | ||
|
||
NAN_METHOD(CalculateSync); | ||
|
||
#endif // EXAMPLES_ASYNC_PI_ESTIMATE_SYNC_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
In this directory run `node-gyp rebuild` and then `node ./addon.js` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#include <napi.h> | ||
#include "sync.h" // NOLINT(build/include) | ||
#include "async.h" // NOLINT(build/include) | ||
|
||
// Expose synchronous and asynchronous access to our | ||
// Estimate() function | ||
Napi::Object Init(Napi::Env env, Napi::Object exports) { | ||
exports.Set(Napi::String::New(env, "calculateSync"), Napi::Function::New(env, CalculateSync)); | ||
exports.Set(Napi::String::New(env, "calculateAsync"), Napi::Function::New(env, CalculateAsync)); | ||
return exports; | ||
} | ||
|
||
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
var addon = require('bindings')('addon'); | ||
var calculations = process.argv[2] || 100000000; | ||
|
||
function printResult(type, pi, ms) { | ||
console.log(type, 'method:'); | ||
console.log('\tπ ≈ ' + pi + | ||
' (' + Math.abs(pi - Math.PI) + ' away from actual)'); | ||
console.log('\tTook ' + ms + 'ms'); | ||
console.log(); | ||
} | ||
|
||
function runSync() { | ||
var start = Date.now(); | ||
// Estimate() will execute in the current thread, | ||
// the next line won't return until it is finished | ||
var result = addon.calculateSync(calculations); | ||
printResult('Sync', result, Date.now() - start); | ||
} | ||
|
||
function runAsync() { | ||
// how many batches should we split the work in to? | ||
var batches = process.argv[3] || 16; | ||
var ended = 0; | ||
var total = 0; | ||
var start = Date.now(); | ||
|
||
function done (err, result) { | ||
total += result; | ||
|
||
// have all the batches finished executing? | ||
if (++ended === batches) { | ||
printResult('Async', total / batches, Date.now() - start); | ||
} | ||
} | ||
|
||
// for each batch of work, request an async Estimate() for | ||
// a portion of the total number of calculations | ||
for (var i = 0; i < batches; i++) { | ||
addon.calculateAsync(calculations / batches, done); | ||
} | ||
} | ||
|
||
runSync(); | ||
runAsync(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#include <napi.h> | ||
#include "pi_est.h" // NOLINT(build/include) | ||
#include "async.h" // NOLINT(build/include) | ||
|
||
class PiWorker : public Napi::AsyncWorker { | ||
public: | ||
PiWorker(Napi::Function& callback, int points) | ||
: Napi::AsyncWorker(callback), points(points), estimate(0) {} | ||
~PiWorker() {} | ||
|
||
// Executed inside the worker-thread. | ||
// It is not safe to access V8, or V8 data structures | ||
// here, so everything we need for input and output | ||
// should go on `this`. | ||
void Execute () { | ||
estimate = Estimate(points); | ||
} | ||
|
||
// Executed when the async work is complete | ||
// this function will be run inside the main event loop | ||
// so it is safe to use V8 again | ||
void OnOK() { | ||
Napi::HandleScope scope(Env()); | ||
Callback().Call({Env().Undefined(), Napi::Number::New(Env(), estimate)}); | ||
} | ||
|
||
private: | ||
int points; | ||
double estimate; | ||
}; | ||
|
||
// Asynchronous access to the `Estimate()` function | ||
Napi::Value CalculateAsync(const Napi::CallbackInfo& info) { | ||
int points = info[0].As<Napi::Number>().Uint32Value(); | ||
Napi::Function callback = info[1].As<Napi::Function>(); | ||
PiWorker* piWorker = new PiWorker(callback, points); | ||
piWorker->Queue(); | ||
return info.Env().Undefined(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef EXAMPLES_ASYNC_PI_ESTIMATE_ASYNC_H_ | ||
#define EXAMPLES_ASYNC_PI_ESTIMATE_ASYNC_H_ | ||
|
||
#include <napi.h> | ||
|
||
Napi::Value CalculateAsync(const Napi::CallbackInfo& info); | ||
|
||
#endif // EXAMPLES_ASYNC_PI_ESTIMATE_ASYNC_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"targets": [ | ||
{ | ||
"target_name": "addon", | ||
"sources": [ | ||
"addon.cc", | ||
"pi_est.cc", | ||
"sync.cc", | ||
"async.cc" | ||
], | ||
'cflags!': [ '-fno-exceptions' ], | ||
'cflags_cc!': [ '-fno-exceptions' ], | ||
'include_dirs': ["<!@(node -p \"require('node-addon-api').include\")"], | ||
'dependencies': ["<!(node -p \"require('node-addon-api').gyp\")"], | ||
'conditions': [ | ||
['OS=="win"', { | ||
"msvs_settings": { | ||
"VCCLCompilerTool": { | ||
"ExceptionHandling": 1 | ||
} | ||
} | ||
}], | ||
['OS=="mac"', { | ||
"xcode_settings": { | ||
"CLANG_CXX_LIBRARY": "libc++", | ||
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', | ||
'MACOSX_DEPLOYMENT_TARGET': '10.7' | ||
} | ||
}] | ||
] | ||
} | ||
] | ||
} |
Oops, something went wrong.