From 260eb5344bf8dfb1ff0055d01d0e2ab97990f91c Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 17 Feb 2014 16:00:01 -0800 Subject: [PATCH] Allow Aphlict to load Javelin and use Javelin class definitions Summary: Ref T4324. The server code is probably going to get a fair amount more complicated, so allow it to load Javelin classes in a mostly-reasonable way. This integration has a few warts, but should be good enough to let us manage complexity through the next iteration of the server. (Mostly I just want the concicse Javelin mechanism for defining new classes.) Version bump is just so I can figure stuff out if this creates any issues for users based on which version of things they're running. Test Plan: Started server, posted some messages through it. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4324 Differential Revision: https://secure.phabricator.com/D8253 --- .../client/PhabricatorNotificationClient.php | 2 +- support/aphlict/server/aphlict_server.js | 27 ++++------- .../aphlict/server/lib/AphlictIDGenerator.js | 18 ++++++++ support/aphlict/server/lib/javelin.js | 13 ++++++ .../rsrc/externals/javelin/core/init_node.js | 45 +++++++++++++++++++ 5 files changed, 85 insertions(+), 20 deletions(-) create mode 100644 support/aphlict/server/lib/AphlictIDGenerator.js create mode 100644 support/aphlict/server/lib/javelin.js create mode 100644 webroot/rsrc/externals/javelin/core/init_node.js diff --git a/src/applications/notification/client/PhabricatorNotificationClient.php b/src/applications/notification/client/PhabricatorNotificationClient.php index f9f78274c2..ae4b6a563b 100644 --- a/src/applications/notification/client/PhabricatorNotificationClient.php +++ b/src/applications/notification/client/PhabricatorNotificationClient.php @@ -2,7 +2,7 @@ final class PhabricatorNotificationClient { - const EXPECT_VERSION = 2; + const EXPECT_VERSION = 3; public static function getServerStatus() { $uri = PhabricatorEnv::getEnvConfig('notification.server-uri'); diff --git a/support/aphlict/server/aphlict_server.js b/support/aphlict/server/aphlict_server.js index c2df180fa0..a3a566b0b2 100644 --- a/support/aphlict/server/aphlict_server.js +++ b/support/aphlict/server/aphlict_server.js @@ -6,6 +6,11 @@ * You can also specify `port`, `admin`, `host` and `log`. */ +var JX = require('./lib/javelin').JX; +JX.require('lib/AphlictIDGenerator', __dirname); + +var id_generator = new JX.AphlictIDGenerator(); + var config = parse_command_line_arguments(process.argv); function parse_command_line_arguments(argv) { @@ -108,25 +113,9 @@ function write_json(socket, data) { var clients = {}; var current_connections = 0; -// According to the internet up to 2^53 can -// be stored in javascript, this is less than that -var MAX_ID = 9007199254740991;//2^53 -1 - -// If we get one connections per millisecond this will -// be fine as long as someone doesn't maintain a -// connection for longer than 6854793 years. If -// you want to write something pretty be my guest - -function generate_id() { - if (typeof generate_id.current_id == 'undefined' || - generate_id.current_id > MAX_ID) { - generate_id.current_id = 0; - } - return generate_id.current_id++; -} var send_server = net.createServer(function(socket) { - var client_id = generate_id(); + var client_id = id_generator.generateNext(); var client_name = '[' + socket.remoteAddress + '] [#' + client_id + '] '; clients[client_id] = socket; @@ -189,11 +178,11 @@ var receive_server = http.createServer(function(request, response) { var status = { 'uptime': (new Date().getTime() - start_time), 'clients.active': current_connections, - 'clients.total': generate_id.current_id || 0, + 'clients.total': id_generator.getTotalCount(), 'messages.in': messages_in, 'messages.out': messages_out, 'log': config.log, - 'version': 2 + 'version': 3 }; response.write(JSON.stringify(status)); diff --git a/support/aphlict/server/lib/AphlictIDGenerator.js b/support/aphlict/server/lib/AphlictIDGenerator.js new file mode 100644 index 0000000000..efea297639 --- /dev/null +++ b/support/aphlict/server/lib/AphlictIDGenerator.js @@ -0,0 +1,18 @@ +var JX = require('javelin').JX; + +JX.install('AphlictIDGenerator', { + + members : { + _next : 0, + + generateNext : function() { + this._next = ((this._next + 1) % 1000000000000); + return this._next; + }, + + getTotalCount : function() { + return this._next; + } + } + +}); diff --git a/support/aphlict/server/lib/javelin.js b/support/aphlict/server/lib/javelin.js new file mode 100644 index 0000000000..e90986a56c --- /dev/null +++ b/support/aphlict/server/lib/javelin.js @@ -0,0 +1,13 @@ +var javelin_root = '../../../../webroot/rsrc/externals/javelin/'; +var JX = require(javelin_root + 'core/init_node.js').JX; + +JX.require('core/util'); +JX.require('core/install'); + +// NOTE: This is faking out a piece of code in JX.install which waits for +// Stratcom before running static initializers. +JX.Stratcom = {ready : true}; +JX.require('core/Event'); +JX.require('core/Stratcom'); + +exports.JX = JX; diff --git a/webroot/rsrc/externals/javelin/core/init_node.js b/webroot/rsrc/externals/javelin/core/init_node.js new file mode 100644 index 0000000000..366d2b1e57 --- /dev/null +++ b/webroot/rsrc/externals/javelin/core/init_node.js @@ -0,0 +1,45 @@ +/** + * Alternative Javelin init file for Node.js. + * + * @javelin-installs JX.enableDispatch + * @javelin-installs JX.onload + * @javelin-installs JX.flushHoldingQueue + * @javelin-installs JX.require + * + * @javelin + */ + +var JX = {}; +var fs = require('fs'); +var vm = require('vm'); +var pathModule = require('path'); + +var noop = function() {}; + +JX.enableDispatch = noop; +JX.flushHoldingQueue = noop; + +JX.onload = function(func) { + func(); +}; + +JX.require = function(thing, relative) { + relative = relative || __dirname + '/..'; + var path = relative + '/' + thing + '.js'; + var content = fs.readFileSync(path); + + var sandbox = { + JX : this, + __DEV__ : 0, + console : console, + window : {}, + require : function (thing) { + return require(pathModule.dirname(path) + '/' + thing); + } + }; + + vm.createScript(content, path) + .runInNewContext(sandbox, path); +}; + +exports.JX = JX;