Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NUODB_NODEJS_REST=true
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ nightly-tests: build
all-tests: build
docker volume create cores
docker volume create valgrind
docker run ${TTY} --env-file .env --cap-add=SYS_PTRACE --memory 1g --volume cores:/cores --volume valgrind:/valgrind --name test --rm --network nuodb-net nuodb/node-nuodb:$(VERSION)-build npm run test test-nightly

docker run ${TTY} --env-file .env --cap-add=SYS_PTRACE --memory 1g --volume cores:/cores --volume valgrind:/valgrind --name test --rm --network nuodb-net nuodb/node-nuodb:$(VERSION)-build npm run test

#:help: test-only | Runs the `test` target, testing the driver without building the Docker.
.PHONY: test-only
Expand All @@ -85,7 +84,7 @@ test-only:
this-test: build
docker volume create cores
docker volume create valgrind
docker run ${TTY} --env-file .env --cap-add=SYS_PTRACE --memory 1g --volume cores:/cores --volume valgrind:/valgrind --name test --rm --network nuodb-net nuodb/node-nuodb:$(VERSION)-build npm run this-test $(test)
docker run ${TTY} --env-file .env --cap-add=SYS_PTRACE --memory 1g --volume cores:/cores --volume valgrind:/valgrind --name test --rm --network nuodb-net nuodb/node-nuodb:$(VERSION)-build npm run this-test $(test) test/shutdown/

#:help: valgrind | Runs the `valgrind` target, building the driver and running a sample application under valgrind.
.PHONY: valgrind
Expand Down
1 change: 1 addition & 0 deletions build-support/scripts/up
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ docker run -d --name ad1 --rm \
-p 8888:8888 \
-p 48004:48004 \
-p 48005:48005 \
-p 9000:9000 \
-e "NUODB_DOMAIN_ENTRYPOINT=ad1" \
"${IMG_NAME}" nuoadmin
echo "Done!"
Expand Down
39 changes: 31 additions & 8 deletions lib/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

require('./logger');

const { RestSvr } = require('./rest');

var addon = require('bindings')('nuodb.node');

var Connection = require('./connection')
Expand All @@ -18,7 +20,8 @@ var SegfaultHandler = require('segfault-handler');
SegfaultHandler.registerHandler("crash.log"); // With no argument, SegfaultHandler will generate a generic log file name

Array.prototype.rotate = (function() {
var unshift = Array.prototype.unshift, splice = Array.prototype.splice;
var unshift = Array.prototype.unshift,
splice = Array.prototype.splice;

return function(count) {
var len = this.length >>> 0;
Expand All @@ -28,11 +31,32 @@ Array.prototype.rotate = (function() {
};
})();

var Driver = function () {
this._driver = new addon.Driver();
class Driver {
//var Driver = function () {
constructor() {
this._driver = new addon.Driver();
}
static {
RestSvr.addInfo("Driver", Driver.getInfo);
}
}

Driver.prototype._connect = function () {
Driver.prototype.getInfo = function() {
const replacer = (key, value) => {
//console.log(key, typeof(value));
if ((key === "livelinessInterval") || (key === "_idleTimeout") || (key === "_idlePrev") || (key === "_idleNext") || (key === "_driver")) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a small suggestion, a more brief way to describe and read this union could be
if (["livelinessInterval", "_idleTimeout", "_idlePrev", "_idleNext", "_driver"].includes(key))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This goes for the other instances of unions in this commit. Again, just a small suggestion for larger unions.

return undefined;
}
return value
}
var retvalue = {
"one": 1,
"two": 2
};
return JSON.stringify(retvalue, replacer, 2);
}

Driver.prototype._connect = function() {
var self = this;
var args = [].slice.call(arguments);
assert(args.length > 0);
Expand All @@ -45,7 +69,7 @@ Driver.prototype._connect = function () {

// n.b. the original callback is always the first form provided
var callback = args[1];
var extension = function (err, instance) {
var extension = function(err, instance) {
if (err) {
callback(err);
return;
Expand Down Expand Up @@ -75,7 +99,7 @@ Driver.prototype.defaults = {
admin: 'random',
}

Driver.prototype.merge = function (config) {
Driver.prototype.merge = function(config) {
var self = this;

config = config || {};
Expand All @@ -84,8 +108,7 @@ Driver.prototype.merge = function (config) {
var value;
if (override === undefined) {
value = process.env['NUODB_' + key.toUpperCase()];
}
else {
} else {
value = process.env[override];
}
return config[key] || value || self.defaults[key];
Expand Down
3 changes: 1 addition & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ var Driver = require('./driver');
var Isolation = require('./isolation');
var RowMode = require('./rowmode');
var Pool = require('./pool');
var Rest = require('./rest');

module.exports = { Driver, Isolation, RowMode, Pool, Rest };
module.exports = { Driver, Isolation, RowMode, Pool };
16 changes: 11 additions & 5 deletions lib/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@

"use strict";

const RestSingleton = require("./rest.js");

const logger = require("./logger");

let Driver = require("./driver");
const Driver = require("./driver");
const { RestSvr } = require("./rest");

const CONNECTION_DEFAULTS = {
autoCommit: true,
Expand All @@ -30,11 +29,18 @@ class Pool {
static LIVELINESS_NOT_RUNNING = "liveliness not running";

static getInfo() {
return JSON.stringify(Pool.allPools);
const replacer = (key, value) => {
if ((key === "livelinessInterval") || (key === "_idleTimeout") || (key === "_idlePrev") || (key === "_idleNext")) {
return undefined;
}
return value
}

return JSON.stringify(Pool.allPools, replacer, 2);
}

static {
RestSingleton.addInfo("Pool", Pool.getInfo);
RestSvr.addInfo("Pool", Pool.getInfo);
}

constructor(args) {
Expand Down
63 changes: 47 additions & 16 deletions lib/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ const http = require('http');
var express = require('express');
const os = require('os');

process.env.NUODB_NODEJS_REST_PORT = process.env.NUODB_NODEJS_REST_PORT || 9000;
const portVarName = 'NUODB_NODEJS_REST_PORT';
var port = 9000;
var port = null;

// Check if default port is overriden with an environment variable
if (process.env[portVarName] && process.env[portVarName].trim() !== '') {
Expand All @@ -26,14 +27,7 @@ if (process.env[portVarName] && process.env[portVarName].trim() !== '') {
// sockets be tracked so at the point you need the server to be shutdown, all open sockets need to be destroyed
// for the server to completely stop so the surrounding process can exit.
class Rest {
static instance = null;

static getInstance() {
if (!Rest.instance) {
Rest.instance = new Rest();
}
return Rest.instance;
}
// static instance = null;

addInfo(key, sfunc) {
this.info[key] = sfunc;
Expand Down Expand Up @@ -61,17 +55,18 @@ class Rest {
}

constructor() {
Rest.instance = this;

this.info = {};
this.logs = [];
this.name = 'REST Server';

if (process.env.NUODB_NODEJS_REST === 'true' || process.env.NODE_NODEJS_REST === '1') {
this._server.listen(port, () => console.log(`Driver REST Listening on port ${port}...`));
process.env.NUODB_NODEJS_REST = process.env.NUODB_NODEJS_REST || 'false';

if ((process.env.NUODB_NODEJS_REST === 'true') || (process.env.NUODB_NODEJS_REST === '1')) {
console.log('Starting Express');
this._express = express();
this._server = http.createServer(this._express);
this._server.listen(port, () => console.log(`Driver REST Listening on port ${port}...`));

// Code to keep track of all sockets that are currently open

Expand All @@ -89,6 +84,12 @@ class Rest {
res.send(JSON.stringify('OK'));
});

this._express.post('/shutdown', (req, res) => {
this.gracefulShutdown();
console.log('Shutdown request received. Closing server.');
res.send('Server is shutting down...');
});

this._express.get('/info/:key', (req, res) => {
const key = req.params.key;
const jsonObject = JSON.parse(this.info[key]());
Expand All @@ -105,10 +106,7 @@ class Rest {
this._express.get('/env', (req, res) => {
res.send((JSON.stringify(process.env, null, 2)));
});

this._server.listen(port, () => console.log(`Driver REST Listening on port ${port}...`));
}

}
}

Expand Down Expand Up @@ -162,4 +160,37 @@ function formatBytes(bytes) {
return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`;
}

module.exports = Rest.getInstance();

// client-shutdown.js
const shutdownServer = async () => {

process.env.NUODB_NODEJS_REST = process.env.NUODB_NODEJS_REST || 'false';
process.env.NUODB_NODEJS_REST_PORT = process.env.NUODB_NODEJS_REST_PORT || 9000;

if ((process.env.NUODB_NODEJS_REST === 'true') || (process.env.NUODB_NODEJS_REST === '1')) {
const url = `http://localhost:${process.env.NUODB_NODEJS_REST_PORT}/shutdown`;
try {
const response = await fetch(url, {
method: 'POST', // Use the POST method for the shutdown action
headers: {
// Add any necessary authorization headers here (omitted for brevity)
'Content-Type': 'application/json'
},
// The body is optional for a simple shutdown trigger
});

if (response.ok) {
const message = await response.text();
console.log(`Shutdown request successful: ${message}`);
} else {
console.error(`Shutdown request failed with status: ${response.status}`);
}
} catch (error) {
console.error('Error making shutdown request:', error.message);
}
}
};

const RestSvr = new Rest();

module.exports = { RestSvr: RestSvr, shutdownServer: shutdownServer, };
Loading