Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update package to run in the most recent version of node #11

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
57a5421
Remove deprecated code that does not run in Node 10.x
ericktpires Dec 11, 2018
a23b57c
Using the most sensible directory for the native files
ericktpires Dec 11, 2018
c66d4ee
Updated linux version
ericktpires Dec 11, 2018
5814cfd
Always build on installation
ericktpires Dec 11, 2018
26432de
Update gitignore
ericktpires Dec 11, 2018
7ac2ad7
Simplify native path search
ericktpires Dec 11, 2018
57e3d5d
Error in logic expression
ericktpires Dec 12, 2018
5d945d5
Correcting tripwire.js
ericktpires Dec 12, 2018
358a1d3
Update README
ericktpires Dec 12, 2018
9d79570
Add option to not throw and exception on timeout
ericktpires Dec 12, 2018
a26a5bc
Pre-compiled binaries for Node 8 to 11 on Windows
Dec 13, 2018
fa7396c
Add API option to set a timeout callback
ericktpires Dec 13, 2018
62b487f
Merge branch 'master' of github.com:erickpires/tripwire
ericktpires Dec 13, 2018
da9c2ce
Updated mac version
ericktpires Dec 13, 2018
549f793
Updated Windows pre-compiled binaries, added bat script to autogenera…
edunmc Dec 13, 2018
cd6c75e
Solved a bug where the tripwire thread could sleep almost double the …
ericktpires Dec 13, 2018
4a47562
Releasing the callback before ending the program otherwise a segfault…
ericktpires Dec 13, 2018
b92dcdd
Removing deprecated code
ericktpires Dec 13, 2018
532000e
Added useRealTime functionality
ericktpires Dec 17, 2018
5ff1735
Uops
ericktpires Dec 17, 2018
4f063df
The code was rolled back and the implementation of the bug where the …
ericktpires Dec 17, 2018
abd2e9c
Reverted and corrected #1 on Linux as well.
ericktpires Dec 18, 2018
70a40ed
Readded AtExit function
ericktpires Dec 19, 2018
46b20b0
Added built native component
ericktpires Dec 19, 2018
8049c10
Support for Node 12 (removing deprecated code)
edunmc Jul 29, 2019
653eb32
Node 12 Windows binaries
edunmc Jul 29, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ results

node_modules
npm-debug.log
build
build
package-lock.json
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Tripwire contains a native extension of node.js and currently supports Windows,

Install with:

Make sure you've installed all the [necessary build tools](https://github.com/TooTallNate/node-gyp#installation) for your platform, then invoke:

```
npm install tripwire
```
Expand Down
12 changes: 6 additions & 6 deletions install.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
if (process.platform !== 'win32') {
require('child_process').spawn('node-gyp', ['rebuild'], {
cwd: __dirname,
stdio: 'inherit'
}).on('close', process.exit).on('error', console.log);
}
let majorVersion = parseInt(process.versions.node.split('.')[0]);

if (!(process.platform === 'win32' && majorVersion >= 8 && majorVersion <= 11)) {
let exec_process = require('child_process').exec("node-gyp configure build");
exec_process.stdout.pipe(process.stdout);
}
Binary file removed lib/native/win32/0.10/ia32/tripwire.node
Binary file not shown.
Binary file removed lib/native/win32/0.10/x64/tripwire.node
Binary file not shown.
Binary file removed lib/native/win32/0.12/ia32/tripwire.node
Binary file not shown.
Binary file removed lib/native/win32/0.12/x64/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/10/ia32/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/10/x64/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/11/ia32/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/11/x64/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/12/ia32/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/12/x64/tripwire.node
Binary file not shown.
Binary file removed lib/native/win32/4.0/ia32/tripwire.node
Binary file not shown.
Binary file removed lib/native/win32/4.0/x64/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/8/ia32/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/8/x64/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/9/ia32/tripwire.node
Binary file not shown.
Binary file added lib/native/win32/9/x64/tripwire.node
Binary file not shown.
28 changes: 15 additions & 13 deletions lib/tripwire.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
var native_path = process.env.TRIPWIRE_NATIVE;
if (!native_path) {
if (process.platform === 'win32') {
if (process.version.match(/^v4\./))
native_path = './native/win32/4.0/' + process.arch + '/tripwire';
else if (process.version.match(/^v0\.12/))
native_path = './native/win32/0.12/' + process.arch + '/tripwire';
else
native_path = './native/win32/0.10/' + process.arch + '/tripwire';
}
else
native_path = require('path').join(__dirname, '../build/Release/tripwire');
function get_native_path() {
var native_path = process.env.TRIPWIRE_NATIVE;

if (!native_path) {
let majorVersion = parseInt(process.versions.node.split('.')[0]);

if (process.platform === 'win32' && majorVersion >= 8 && majorVersion <= 12)
native_path = './native/win32/' + majorVersion + '/' + process.arch + '/tripwire';
else
native_path = require('path').join(__dirname, '../build/Release/tripwire');
}

return native_path;
}
module.exports = require(native_path);

module.exports = require(get_native_path());
26 changes: 19 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,34 @@
},
"version": "4.2.0-pre",
"description": "Break out from scripts blocking node.js event loop",
"tags" : ["event loop", "hang"],
"tags": [
"event loop",
"hang"
],
"main": "./lib/tripwire.js",
"engines": { "node": "0.10.x || 0.12.x || 4.x" },
"licenses": [ { "type": "Apache", "url": "http://www.apache.org/licenses/LICENSE-2.0" } ],
"engines": {
"node": "0.10.x || 0.12.x || 4.x"
},
"licenses": [
{
"type": "Apache",
"url": "http://www.apache.org/licenses/LICENSE-2.0"
}
],
"homepage": "https://github.com/tjanczuk/tripwire",
"dependencies": {
"nan": "^2.0.8"
"child_process": "^1.0.2",
"deasync": "^0.1.14",
"nan": "^2.14.0"
},
"repository": {
"type": "git",
"url": "[email protected]:tjanczuk/tripwire.git"
},
"bugs" : {
"url" : "http://github.com/tjanczuk/tripwire/issues"
"bugs": {
"url": "http://github.com/tjanczuk/tripwire/issues"
},
"scripts": {
"install": "node install.js"
}
}
}
36 changes: 36 additions & 0 deletions recompile_windows_binaries.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
mkdir "lib\native\win32\8\x64\"
mkdir "lib\native\win32\9\x64\"
mkdir "lib\native\win32\10\x64\"
mkdir "lib\native\win32\11\x64\"
mkdir "lib\native\win32\12\x64\"

mkdir "lib\native\win32\8\ia32\"
mkdir "lib\native\win32\9\ia32\"
mkdir "lib\native\win32\10\ia32\"
mkdir "lib\native\win32\11\ia32\"
mkdir "lib\native\win32\12\ia32\"

call node-gyp clean configure build --arch=x64 --target=v8.16.0
move /Y "build\Release\tripwire.node" "lib\native\win32\8\x64\"
call node-gyp clean configure build --arch=ia32 --target=v8.16.0
move /Y "build\Release\tripwire.node" "lib\native\win32\8\ia32\"

call node-gyp clean configure build --arch=x64 --target=v9.11.2
move /Y "build\Release\tripwire.node" "lib\native\win32\9\x64\"
call node-gyp clean configure build --arch=ia32 --target=v9.11.2
move /Y "build\Release\tripwire.node" "lib\native\win32\9\ia32\"

call node-gyp clean configure build --arch=x64 --build_v8_with_gn=false --target=v10.16.0
move /Y "build\Release\tripwire.node" "lib\native\win32\10\x64\"
call node-gyp clean configure build --arch=ia32 --build_v8_with_gn=false --target=v10.16.0
move /Y "build\Release\tripwire.node" "lib\native\win32\10\ia32\"

call node-gyp clean configure build --arch=x64 --build_v8_with_gn=false --target=v11.15.0
move /Y "build\Release\tripwire.node" "lib\native\win32\11\x64\"
call node-gyp clean configure build --arch=ia32 --build_v8_with_gn=false --target=v11.15.0
move /Y "build\Release\tripwire.node" "lib\native\win32\11\ia32\"

call node-gyp clean configure build --arch=x64 --build_v8_with_gn=false --target=v12.7.0
move /Y "build\Release\tripwire.node" "lib\native\win32\12\x64\"
call node-gyp clean configure build --arch=ia32 --build_v8_with_gn=false --target=v12.7.0
move /Y "build\Release\tripwire.node" "lib\native\win32\12\ia32\"
85 changes: 78 additions & 7 deletions src/tripwire.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,28 @@ unsigned int tripwireThreshold;
Nan::Persistent<v8::Value> context;
int terminated;
v8::Isolate* isolate;
bool shouldThrowException = true;
bool useRealTime = false;

bool hasTimeoutCallback = false;
v8::Local<v8::Value> argv[] {Nan::Null()};
Nan::Callback timeoutCallback;

#if (NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION)
void interruptCallback(v8::Isolate* isolate, void* data)
{
Nan::RunScript(Nan::CompileScript(Nan::New<v8::String>(
"process.nextTick(function () { throw new Error('Blocked event loop'); });"
).ToLocalChecked()).ToLocalChecked());
).ToLocalChecked()
).ToLocalChecked());
}
#endif

void timeoutCallbackCaller(v8::Isolate* isolate, void* data)
{
Nan::Call(timeoutCallback, 1, argv);
}

NAN_METHOD(clearTripwire)
{
// Seting tripwireThreshold to 0 indicates to the worker process that
Expand All @@ -35,18 +47,18 @@ NAN_METHOD(clearTripwire)
NAN_METHOD(resetTripwire)
{
Nan::EscapableHandleScope scope;
if (0 == info.Length() || !info[0]->IsUint32()) {
if (0 == info.Length() || Nan::To<v8::Uint32>(info[0]).IsEmpty()) {
Nan::ThrowError("First agument must be an integer time threshold in milliseconds.");
info.GetReturnValue().SetUndefined();
}
else if (0 == info[0]->ToUint32()->Value()) {
else if (0 == Nan::To<v8::Uint32>(info[0]).ToLocalChecked()->Value()) {
Nan::ThrowError("The time threshold for blocking operations must be greater than 0.");
info.GetReturnValue().SetUndefined();
}
else {
clearTripwire(info);

tripwireThreshold = info[0]->ToUint32()->Value();
tripwireThreshold = Nan::To<v8::Uint32>(info[0]).ToLocalChecked()->Value();
isolate = info.GetIsolate();
if (info.Length() > 1)
{
Expand All @@ -71,20 +83,79 @@ NAN_METHOD(getContext)
info.GetReturnValue().SetUndefined();
}

NAN_METHOD(setShouldThrowException)
{
Nan::EscapableHandleScope scope;

if(info.Length() == 0 || Nan::To<v8::Boolean>(info[0]).IsEmpty()) {
Nan::ThrowError("First agument must be a boolean.");
info.GetReturnValue().SetUndefined();
}
else {
shouldThrowException = Nan::To<v8::Boolean>(info[0]).ToLocalChecked()->IsTrue();
}
}

NAN_METHOD(setUseRealTime)
{
Nan::EscapableHandleScope scope;

if(info.Length() == 0 || Nan::To<v8::Boolean>(info[0]).IsEmpty()) {
Nan::ThrowError("First agument must be a boolean.");
info.GetReturnValue().SetUndefined();
}
else {
useRealTime = Nan::To<v8::Boolean>(info[0]).ToLocalChecked()->IsTrue();
}
}

NAN_METHOD(setTimeoutCallback)
{
Nan::EscapableHandleScope scope;

if(info.Length() == 0 || Nan::To<v8::Function>(info[0]).IsEmpty()) {
Nan::ThrowError("First agument must be a function.");
info.GetReturnValue().SetUndefined();
}
else {
hasTimeoutCallback = true;
const v8::Local<v8::Function> func = Nan::To<v8::Function>(info[0]).ToLocalChecked();
timeoutCallback.Reset(func);
}
}

void cleanUpFunction(void*)
{
timeoutCallback.Reset();
}

NAN_MODULE_INIT(init)
{
initCore();
isolate = v8::Isolate::GetCurrent();
v8::Local<v8::Context> context = v8::Context::New(isolate);
terminated = 0;
Nan::Set(target,
Nan::New<v8::String>("resetTripwire").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(resetTripwire)->GetFunction());
Nan::New<v8::FunctionTemplate>(resetTripwire)->GetFunction(context).ToLocalChecked());
Nan::Set(target,
Nan::New<v8::String>("clearTripwire").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(clearTripwire)->GetFunction());
Nan::New<v8::FunctionTemplate>(clearTripwire)->GetFunction(context).ToLocalChecked());
Nan::Set(target,
Nan::New<v8::String>("getContext").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(getContext)->GetFunction());
Nan::New<v8::FunctionTemplate>(getContext)->GetFunction(context).ToLocalChecked());

Nan::Set(target,
Nan::New<v8::String>("setShouldThrowException").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(setShouldThrowException)->GetFunction(context).ToLocalChecked());
Nan::Set(target,
Nan::New<v8::String>("setUseRealTime").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(setUseRealTime)->GetFunction(context).ToLocalChecked());
Nan::Set(target,
Nan::New<v8::String>("setTimeoutCallback").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(setTimeoutCallback)->GetFunction(context).ToLocalChecked());

node::AtExit(cleanUpFunction, NULL);
}

NODE_MODULE(tripwire, init);
27 changes: 22 additions & 5 deletions src/tripwire_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ pthread_cond_t tripwireCondition = PTHREAD_COND_INITIALIZER;
extern unsigned int tripwireThreshold;
extern int terminated;
extern v8::Isolate* isolate;

extern bool shouldThrowException;
extern bool hasTimeoutCallback;
extern void timeoutCallbackCaller(v8::Isolate *isolate, void *data);


#if (NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION)
extern void interruptCallback(v8::Isolate *isolate, void *data);
#endif
Expand All @@ -24,6 +30,7 @@ void* tripwireWorker(void* data)
int skipTimeCapture = 0;
struct timespec timeout;
struct rusage start, end;
unsigned int elapsedMs = 0;

// This thread monitors the elapsed CPU utilization time of the node.js thread and forces V8 to terminate
// execution if it exceeds the preconfigured tripwireThreshold.
Expand Down Expand Up @@ -53,9 +60,10 @@ void* tripwireWorker(void* data)
}
else
{
unsigned int remainingTime = tripwireThreshold < elapsedMs ? 0 : tripwireThreshold - elapsedMs;
clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec += tripwireThreshold / 1000;
timeout.tv_nsec += (tripwireThreshold % 1000) * 1000000;
timeout.tv_sec += remainingTime / 1000;
timeout.tv_nsec += (remainingTime % 1000) * 1000000;
waitResult = pthread_cond_timedwait(&tripwireCondition, &tripwireMutex, &timeout);
}
pthread_mutex_unlock(&tripwireMutex);
Expand Down Expand Up @@ -83,7 +91,7 @@ void* tripwireWorker(void* data)

// Process execution times are reported in seconds and microseconds. Convert to milliseconds.

unsigned int elapsedMs =
elapsedMs =
((end.ru_utime.tv_sec - start.ru_utime.tv_sec) + (end.ru_stime.tv_sec - start.ru_stime.tv_sec))
* 1000
+ ((end.ru_utime.tv_usec - start.ru_utime.tv_usec) + (end.ru_stime.tv_usec - start.ru_stime.tv_usec))
Expand All @@ -97,9 +105,18 @@ void* tripwireWorker(void* data)
if (elapsedMs >= tripwireThreshold)
{
terminated = 1;
v8::V8::TerminateExecution(isolate);
isolate->TerminateExecution();

if(hasTimeoutCallback)
{
isolate->RequestInterrupt(timeoutCallbackCaller, NULL);
}

#if (NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION)
isolate->RequestInterrupt(interruptCallback, NULL);
if(shouldThrowException)
{
isolate->RequestInterrupt(interruptCallback, NULL);
}
#endif
}
else
Expand Down
Loading