[Groonga-commit] droonga/express-droonga at ae0426f [master] Add module to wrap Serf agent

Back to archive index

YUKI Hiroshi null+****@clear*****
Wed Nov 5 11:49:31 JST 2014


YUKI Hiroshi	2014-11-05 11:49:31 +0900 (Wed, 05 Nov 2014)

  New Revision: ae0426fbe165e4f618b6b5993fc762dd501252da
  https://github.com/droonga/express-droonga/commit/ae0426fbe165e4f618b6b5993fc762dd501252da

  Message:
    Add module to wrap Serf agent

  Added files:
    lib/serf/agent.js

  Added: lib/serf/agent.js (+127 -0) 100644
===================================================================
--- /dev/null
+++ lib/serf/agent.js    2014-11-05 11:49:31 +0900 (3e38430)
@@ -0,0 +1,127 @@
+/**
+ * usage:
+ *   var Agent = require('lib/serf/agent');
+ *   var serf = new Agent({
+ *                serf: '/path/to/serf',
+ *                name: 'node0:10041/droonga',
+ *                otherHostNames: ['node0:7946', 'node1:8946', 'node2', ...]
+ *              });
+ *   serf.start()
+ *     .then(function() { ... })
+ *     .catch(function(error) { ... });
+ *   serf.shutdown();
+ */
+
+var exec  = require('child_process').exec,
+    fs    = require('fs'),
+    path  = require('path'),
+    Q     = require('q'),
+    spawn = require('child_process').spawn;
+
+var ConsoleLogger = require('../console-logger').ConsoleLogger,
+    Downloader    = require('./downloader');
+
+var NODE_NAME_PATTERN = /^([^:]+):(\d+)\/(.+)$/;
+
+function Agent(options) {
+  options = options || {};
+
+  this._logger = options.logger || new ConsoleLogger();
+
+  this._name = options.name;
+  this._serf = options.serf || 'serf';
+  if (this._serf.charAt(0) == '.')
+    this._serf = path.resolve(this._serf);
+
+  this._otherHostNames = options.otherHostNames || options.otherHostName || [];
+  if (!Array.isArray(this._otherHostNames))
+    this._otherHostNames = [this._otherHostNames];
+
+  var matched = String(this._name).match(NODE_NAME_PATTERN);
+  if (!matched)
+    throw new Error('Name must be <host name>:<port number>/<tag name> !');
+
+  this._hostName = matched[1];
+  this._port     = matched[2];
+  this._tag      = matched[3];
+
+  this._agentProcess = null;
+  this.shutdown = this.shutdown.bind(this);
+}
+Agent.prototype = {
+  start: function() {
+    this._logger.debug('Starting Serf agent (' + this._serf + ')');
+    return Q.Promise((function(resolve, reject, notify) {
+      if (this._agentProcess)
+        return resolve();
+
+      if (this._serf.charAt(0) == '/' &&
+          !fs.existsSync(this._serf)) {
+        this._logger.info('Serf command is not found. Install Serf automatically.');
+        new Downloader().saveTo(path.dirname(this._serf))
+          .then((function() {
+            this.start().then(resolve).catch(reject);
+          }).bind(this))
+          .catch(reject);
+        return;
+      }
+
+      exec(this._serf + ' version', (function(error, stdin, stdout) {
+        if (error)
+          return reject(new Error('Serf is not available.'));
+        try {
+          this.tryStart();
+          resolve();
+        } catch(error) {
+          reject(error);
+        }
+      }).bind(this));
+    }).bind(this));
+  },
+
+  tryStart: function() {
+    var eventHandlerPath = path.join(__dirname, '..', '..', 'bin',
+                                       'express-droonga-serf-event-handler');
+    var agentArgs = [
+      'agent',
+      '-node', this._name,
+      '-bind', this._hostName + ':8946',
+      // '-event-handler', eventHandlerPath,
+      // '-log-level', this._logLevel,
+      '-tag', 'role=protocol-adapter'
+    ];
+    this._otherHostNames.forEach(function(hostName) {
+      agentArgs.push('-retry-join');
+      if (!/^[^:]+:\d+$/.test(hostName))
+        hostName = hostName + ':7946';
+      agentArgs.push(hostName);
+    });
+    try {
+      this._logger.info('Starting Serf agent: ' + this._serf + ' ' + agentArgs.join(' '));
+      this._agentProcess = spawn(this._serf, agentArgs);
+      this._agentProcess.on('close', (function(exitStatusCode) {
+        if (exitStatusCode != 0)
+          this._logger.error(new Error('Serf agent is closed with error: ' + exitStatusCode));
+        this._agentProcess = null;
+      }).bind(this));
+    } catch(error) {
+      this._agentProcess = null;
+      this._logger.error(error);
+    }
+  },
+
+  shutdown: function() {
+    this._logger.info('Shutting down Serf agent');
+    if (!this._agentProcess)
+      return;
+    try {
+      this._agentProcess.removeAllListeners();
+      this._agentProcess.kill();
+      this._agentProcess = null;
+    } catch(error) {
+      this._logger.error(error);
+    }
+  }
+};
+
+module.exports = Agent;
-------------- next part --------------
HTML����������������������������...
下載 



More information about the Groonga-commit mailing list
Back to archive index