diff --git a/client.js b/client.js index 562ee1e..1e14054 100644 --- a/client.js +++ b/client.js @@ -25,17 +25,17 @@ function startServer(opts) { } function getConnection(opts) { - if (!opts.sock) { - opts.sock = opts.filename + '.sock'; - } - return new Promise(function (resolve) { setTimeout(function () { var WebSocket = require('ws'); var ws = new WebSocket('ws+unix:' + opts.sock); - if (opts.server) { - return startServer(opts); + if (opts.serve) { + console.log("[EXPLICIT SERVER] #################################################"); + return startServer(opts).then(function (client) { + // ws.masterClient = client; + resolve({ masterClient: client }); + }); } ws.on('error', function (err) { @@ -48,7 +48,8 @@ function getConnection(opts) { }, 100 + (Math.random() * 250)); } - if ('ENOENT' === err.code || 'ECONNREFUSED' === err.code) { + if (!opts.connect && ('ENOENT' === err.code || 'ECONNREFUSED' === err.code)) { + console.log('[NO SERVER] attempting to create a server #######################'); return startServer(opts).then(function (client) { // ws.masterClient = client; resolve({ masterClient: client }); @@ -68,8 +69,38 @@ function getConnection(opts) { } function create(opts) { + if (!opts.sock) { + opts.sock = opts.filename + '.sock'; + } + + var promise; + var numcpus = require('os').cpus().length; + if (opts.standalone || (1 === numcpus && !opts.serve && !opts.connect)) { + return require('./wrapper').create(opts); + } + + function retryServe() { + return startServer(opts).then(function (client) { + // ws.masterClient = client; + return { masterClient: client }; + }, function () { + retryServe(); + }); + } + + if (opts.serve) { + console.log('[EXPLICIT]'); + promise = retryServe(); + } else { + promise = getConnection(opts); + } + /* + if (opts.connect) { + } + */ + // TODO maybe use HTTP POST instead? - return getConnection(opts).then(function (ws) { + return promise.then(function (ws) { if (ws.masterClient) { console.log('[MASTER CLIENT] found'); return ws.masterClient; diff --git a/cluster.js b/cluster.js new file mode 100644 index 0000000..d9f722c --- /dev/null +++ b/cluster.js @@ -0,0 +1,21 @@ +'use strict'; + +var sqlite3 = require('./index'); + +function create(opts) { + var cluster = require('cluster'); + var numCores = require('os').cpus().length; + + if (!opts.serve && ('boolean' !== typeof opts.serve)) { + opts.serve = (numCores > 1) && cluster.isMaster; + } + + if (!opts.connect && ('boolean' !== typeof opts.connect)) { + opts.connect = (numCores > 1) && cluster.isWorker; + } + + return sqlite3.create(opts); +} + +module.exports.sanitize = sqlite3.sanitize; +module.exports.create = create; diff --git a/index.js b/index.js index aad176a..a961216 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,3 @@ 'use strict'; -var numcpus = require('os').cpus().length; -var sqlite3; - -if (numcpus >= 2) { - sqlite3 = require('./client'); -} else { - sqlite3 = require('./wrapper'); -} - -module.exports = sqlite3; +module.exports = require('./client'); diff --git a/standalone.js b/standalone.js new file mode 100644 index 0000000..770044d --- /dev/null +++ b/standalone.js @@ -0,0 +1,16 @@ +'use strict'; + +var sqlite3 = require('./index'); + +function create(opts) { + opts.standalone = true; + + // TODO if cluster *is* used issue a warning? + // I suppose the user could be issuing a different filename for each + // ... but then they have no need to use this module, right? + + return sqlite3.create(opts); +} + +module.exports.sanitize = sqlite3.sanitize; +module.exports.create = create; diff --git a/test-cluster.js b/test-cluster.js new file mode 100644 index 0000000..e897a61 --- /dev/null +++ b/test-cluster.js @@ -0,0 +1,38 @@ +'use strict'; + +var cluster = require('cluster'); +var numCores = require('os').cpus().length; +var i; + +function run() { + var sqlite3 = require('./cluster'); + + sqlite3.create({ + key: '00000000000000000000000000000000' + , bits: 128 + , filename: '/tmp/test.cluster.sqlcipher' + , verbose: null + , standalone: null + , serve: null + , connect: null + }).then(function (client) { + client.run("SELECT 1", [], function (err) { + if (err) { + console.error('[ERROR]', cluster.isMaster && '0' || cluster.worker.id); + console.error(err); + return; + } + + console.log('[this]', cluster.isMaster && '0' || cluster.worker.id); + console.log(this); + }); + }); +} + +if (cluster.isMaster) { + for (i = 1; i <= numCores; i += 1) { + cluster.fork(); + } +} + +run(); diff --git a/test-standalone.js b/test-standalone.js new file mode 100644 index 0000000..22ededd --- /dev/null +++ b/test-standalone.js @@ -0,0 +1,28 @@ +'use strict'; + +function run() { + var sqlite3 = require('./standalone'); + + sqlite3.create({ + key: '00000000000000000000000000000000' + , bits: 128 + , filename: '/tmp/test.cluster.sqlcipher' + , verbose: null + , standalone: true + , serve: null + , connect: null + }).then(function (client) { + client.run("SELECT 1", [], function (err) { + if (err) { + console.error('[ERROR] standalone'); + console.error(err); + return; + } + + console.log('[this] standalone'); + console.log(this); + }); + }); +} + +run();