feat: 초기 프로젝트 설정 및 룰.md 파일 추가

This commit is contained in:
2025-07-28 09:53:31 +09:00
commit 09a4d38512
8165 changed files with 1021855 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
0.0.1 / 2010-01-03
==================
* Initial release

View File

@@ -0,0 +1,7 @@
test:
@./node_modules/.bin/mocha \
--require should \
--reporter spec
.PHONY: test

View File

@@ -0,0 +1,57 @@
# configurable
Configuration mixin.
## API
Make something configurable:
```js
var Configurable = require('configurable');
// plain obj
var obj = {};
Configurable(obj);
// returns the obj itself
var obj = Configurable({});
// make a prototype configurable
Configurable(MyThing.prototype);
```
```js
.get(name)
.set(name, val)
.set(obj)
.enable(name)
.disable(name)
.enabled(name)
.disabled(name)
```
## License
(The MIT License)
Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,2 @@
module.exports = require('./lib/configurable');

View File

@@ -0,0 +1,47 @@
/**
* Make `obj` configurable.
*
* @param {Object} obj
* @return {Object} the `obj`
* @api public
*/
module.exports = function(obj){
obj.settings = {};
obj.set = function(name, val){
if (1 == arguments.length) {
for (var key in name) {
this.set(key, name[key]);
}
} else {
this.settings[name] = val;
}
return this;
};
obj.get = function(name){
return this.settings[name];
};
obj.enable = function(name){
return this.set(name, true);
};
obj.disable = function(name){
return this.set(name, false);
};
obj.enabled = function(name){
return !! this.get(name);
};
obj.disabled = function(name){
return ! this.get(name);
};
return obj;
};

View File

@@ -0,0 +1,68 @@
{
"_args": [
[
{
"raw": "configurable@0.0.1",
"scope": null,
"escapedName": "configurable",
"name": "configurable",
"rawSpec": "0.0.1",
"spec": "0.0.1",
"type": "version"
},
"/home/unitech/keymetrics/pm2-axon"
]
],
"_from": "configurable@0.0.1",
"_id": "configurable@0.0.1",
"_inCache": true,
"_installable": true,
"_location": "/configurable",
"_phantomChildren": {},
"_requested": {
"raw": "configurable@0.0.1",
"scope": null,
"escapedName": "configurable",
"name": "configurable",
"rawSpec": "0.0.1",
"spec": "0.0.1",
"type": "version"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/configurable/-/configurable-0.0.1.tgz",
"_shasum": "47d75b727b51b4eb84c1dadafe3f8240313833b1",
"_shrinkwrap": null,
"_spec": "configurable@0.0.1",
"_where": "/home/unitech/keymetrics/pm2-axon",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
},
"dependencies": {},
"description": "Configuration mixin",
"devDependencies": {
"mocha": "*",
"should": "*"
},
"directories": {},
"dist": {
"shasum": "47d75b727b51b4eb84c1dadafe3f8240313833b1",
"tarball": "https://registry.npmjs.org/configurable/-/configurable-0.0.1.tgz"
},
"keywords": [
"configuration"
],
"main": "index",
"maintainers": [
{
"name": "tjholowaychuk",
"email": "tj@vision-media.ca"
}
],
"name": "configurable",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"version": "0.0.1"
}

44
api.hyungi.net/node_modules/pm2-axon/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
/**
* Constructors.
*/
exports.PubEmitterSocket = require('./sockets/pub-emitter');
exports.SubEmitterSocket = require('./sockets/sub-emitter');
exports.PushSocket = require('./sockets/push');
exports.PullSocket = require('./sockets/pull');
exports.PubSocket = require('./sockets/pub');
exports.SubSocket = require('./sockets/sub');
exports.ReqSocket = require('./sockets/req');
exports.RepSocket = require('./sockets/rep');
exports.Socket = require('./sockets/sock');
/**
* Socket types.
*/
exports.types = {
'pub-emitter': exports.PubEmitterSocket,
'sub-emitter': exports.SubEmitterSocket,
'push': exports.PushSocket,
'pull': exports.PullSocket,
'pub': exports.PubSocket,
'sub': exports.SubSocket,
'req': exports.ReqSocket,
'rep': exports.RepSocket
};
/**
* Return a new socket of the given `type`.
*
* @param {String} type
* @param {Object} options
* @return {Socket}
* @api public
*/
exports.socket = function(type, options){
var fn = exports.types[type];
if (!fn) throw new Error('invalid socket type "' + type + '"');
return new fn(options);
};

View File

@@ -0,0 +1,71 @@
/**
* Module dependencies.
*/
var debug = require('debug')('axon:queue');
/**
* Queue plugin.
*
* Provides an `.enqueue()` method to the `sock`. Messages
* passed to `enqueue` will be buffered until the next
* `connect` event is emitted.
*
* Emits:
*
* - `drop` (msg) when a message is dropped
* - `flush` (msgs) when the queue is flushed
*
* @param {Object} options
* @api private
*/
module.exports = function(options){
options = options || {};
return function(sock){
/**
* Message buffer.
*/
sock.queue = [];
/**
* Flush `buf` on `connect`.
*/
sock.on('connect', function(){
var prev = sock.queue;
var len = prev.length;
sock.queue = [];
debug('flush %d messages', len);
for (var i = 0; i < len; ++i) {
this.send.apply(this, prev[i]);
}
sock.emit('flush', prev);
});
/**
* Pushes `msg` into `buf`.
*/
sock.enqueue = function(msg){
var hwm = sock.settings.hwm;
if (sock.queue.length >= hwm) return drop(msg);
sock.queue.push(msg);
};
/**
* Drop the given `msg`.
*/
function drop(msg) {
debug('drop');
sock.emit('drop', msg);
}
};
};

View File

@@ -0,0 +1,55 @@
/**
* Deps.
*/
var slice = require('../utils').slice;
/**
* Round-robin plugin.
*
* Provides a `send` method which will
* write the `msg` to all connected peers.
*
* @param {Object} options
* @api private
*/
module.exports = function(options){
options = options || {};
var fallback = options.fallback || function(){};
return function(sock){
/**
* Bind callback to `sock`.
*/
fallback = fallback.bind(sock);
/**
* Initialize counter.
*/
var n = 0;
/**
* Sends `msg` to all connected peers round-robin.
*/
sock.send = function(){
var socks = this.socks;
var len = socks.length;
var sock = socks[n++ % len];
var msg = slice(arguments);
if (sock && sock.writable) {
sock.write(this.pack(msg));
} else {
fallback(msg);
}
};
};
};

View File

@@ -0,0 +1,26 @@
/**
* Module dependencies.
*/
var PubSocket = require('./pub');
/**
* Expose `SubPubEmitterSocket`.
*/
module.exports = PubEmitterSocket;
/**
* Initialzie a new `PubEmitterSocket`.
*
* @api private
*/
function PubEmitterSocket() {
this.sock = new PubSocket;
this.emit = this.sock.send.bind(this.sock);
this.bind = this.sock.bind.bind(this.sock);
this.connect = this.sock.connect.bind(this.sock);
this.close = this.sock.close.bind(this.sock);
}

View File

@@ -0,0 +1,77 @@
/**
* Module dependencies.
*/
var Socket = require('./sock');
var slice = require('../utils').slice;
/**
* Expose `PubSocket`.
*/
module.exports = PubSocket;
/**
* Initialize a new `PubSocket`.
*
* @api private
*/
function PubSocket() {
Socket.call(this);
}
/**
* Inherits from `Socket.prototype`.
*/
PubSocket.prototype.__proto__ = Socket.prototype;
/**
* Send `msg` to all established peers.
*
* @param {Mixed} msg
* @api public
*/
PubSocket.prototype.send = function(msg){
var socks = this.socks;
var len = socks.length;
var buf = this.pack(arguments);
for (var sock of socks) {
if (sock.writable) sock.write(buf);
}
return this;
};
PubSocket.prototype.sendv2 = function(data, cb){
var socks = this.socks;
var len = socks.length;
var sock;
if (len == 0)
return process.nextTick(cb);
var buf = this.pack([data]);
var i = 0;
socks.forEach(function(sock) {
if (sock.writable)
sock.write(buf, function() {
i++;
if (i == len)
process.nextTick(cb);
});
else {
i++;
if (i == len)
process.nextTick(cb);
}
});
return this;
};

View File

@@ -0,0 +1,37 @@
/**
* Module dependencies.
*/
var Socket = require('./sock');
/**
* Expose `PullSocket`.
*/
module.exports = PullSocket;
/**
* Initialize a new `PullSocket`.
*
* @api private
*/
function PullSocket() {
Socket.call(this);
// TODO: selective reception
}
/**
* Inherits from `Socket.prototype`.
*/
PullSocket.prototype.__proto__ = Socket.prototype;
/**
* Pull sockets should not send messages.
*/
PullSocket.prototype.send = function(){
throw new Error('pull sockets should not send messages');
};

View File

@@ -0,0 +1,32 @@
/**
* Module dependencies.
*/
var roundrobin = require('../plugins/round-robin');
var queue = require('../plugins/queue');
var Socket = require('./sock');
/**
* Expose `PushSocket`.
*/
module.exports = PushSocket;
/**
* Initialize a new `PushSocket`.
*
* @api private
*/
function PushSocket() {
Socket.call(this);
this.use(queue());
this.use(roundrobin({ fallback: this.enqueue }));
}
/**
* Inherits from `Socket.prototype`.
*/
PushSocket.prototype.__proto__ = Socket.prototype;

View File

@@ -0,0 +1,73 @@
/**
* Module dependencies.
*/
var slice = require('../utils').slice;
var debug = require('debug')('axon:rep');
var Message = require('amp-message');
var Socket = require('./sock');
/**
* Expose `RepSocket`.
*/
module.exports = RepSocket;
/**
* Initialize a new `RepSocket`.
*
* @api private
*/
function RepSocket() {
Socket.call(this);
}
/**
* Inherits from `Socket.prototype`.
*/
RepSocket.prototype.__proto__ = Socket.prototype;
/**
* Incoming.
*
* @param {net.Socket} sock
* @return {Function} closure(msg, mulitpart)
* @api private
*/
RepSocket.prototype.onmessage = function(sock){
var self = this;
return function (buf){
var msg = new Message(buf);
var args = msg.args;
var id = args.pop();
args.unshift('message');
args.push(reply);
self.emit.apply(self, args);
function reply() {
var fn = function(){};
var args = slice(arguments);
args[0] = args[0] || null;
var hasCallback = 'function' == typeof args[args.length - 1];
if (hasCallback) fn = args.pop();
args.push(id);
if (sock.writable) {
sock.write(self.pack(args), function(){ fn(true) });
return true;
} else {
debug('peer went away');
process.nextTick(function(){ fn(false) });
return false;
}
}
};
};

101
api.hyungi.net/node_modules/pm2-axon/lib/sockets/req.js generated vendored Normal file
View File

@@ -0,0 +1,101 @@
/**
* Module dependencies.
*/
var debug = require('debug')('axon:req');
var queue = require('../plugins/queue');
var slice = require('../utils').slice;
var Message = require('amp-message');
var Socket = require('./sock');
/**
* Expose `ReqSocket`.
*/
module.exports = ReqSocket;
/**
* Initialize a new `ReqSocket`.
*
* @api private
*/
function ReqSocket() {
Socket.call(this);
this.n = 0;
this.ids = 0;
this.callbacks = {};
this.identity = this.get('identity');
this.use(queue());
}
/**
* Inherits from `Socket.prototype`.
*/
ReqSocket.prototype.__proto__ = Socket.prototype;
/**
* Return a message id.
*
* @return {String}
* @api private
*/
ReqSocket.prototype.id = function(){
return this.identity + ':' + this.ids++;
};
/**
* Emits the "message" event with all message parts
* after the null delimeter part.
*
* @param {net.Socket} sock
* @return {Function} closure(msg, multipart)
* @api private
*/
ReqSocket.prototype.onmessage = function(){
var self = this;
return function(buf){
var msg = new Message(buf);
var id = msg.pop();
var fn = self.callbacks[id];
if (!fn) return debug('missing callback %s', id);
fn.apply(null, msg.args);
delete self.callbacks[id];
};
};
/**
* Sends `msg` to the remote peers. Appends
* the null message part prior to sending.
*
* @param {Mixed} msg
* @api public
*/
ReqSocket.prototype.send = function(msg){
var socks = this.socks;
var len = socks.length;
var sock = socks[this.n++ % len];
var args = slice(arguments);
if (sock) {
var hasCallback = 'function' == typeof args[args.length - 1];
if (!hasCallback) args.push(function(){});
var fn = args.pop();
fn.id = this.id();
this.callbacks[fn.id] = fn;
args.push(fn.id);
}
if (sock) {
sock.write(this.pack(args));
} else {
debug('no connected peers');
this.enqueue(args);
}
};

View File

@@ -0,0 +1,415 @@
/**
* Module dependencies.
*/
var Emitter = require('events').EventEmitter;
var Configurable = require('../configurable');
var debug = require('debug')('axon:sock');
var Message = require('amp-message');
var Parser = require('amp').Stream;
var url = require('url');
var net = require('net');
var fs = require('fs');
/**
* Errors to ignore.
*/
var ignore = [
'ECONNREFUSED',
'ECONNRESET',
'ETIMEDOUT',
'EHOSTUNREACH',
'ENETUNREACH',
'ENETDOWN',
'EPIPE',
'ENOENT'
];
/**
* Expose `Socket`.
*/
module.exports = Socket;
/**
* Initialize a new `Socket`.
*
* A "Socket" encapsulates the ability of being
* the "client" or the "server" depending on
* whether `connect()` or `bind()` was called.
*
* @api private
*/
function Socket() {
var self = this;
this.opts = {};
this.server = null;
this.socks = [];
this.settings = {};
this.set('hwm', Infinity);
this.set('identity', String(process.pid));
this.set('retry timeout', 100);
this.set('retry max timeout', 5000);
}
/**
* Inherit from `Emitter.prototype`.
*/
Socket.prototype.__proto__ = Emitter.prototype;
/**
* Make it configurable `.set()` etc.
*/
Configurable(Socket.prototype);
/**
* Use the given `plugin`.
*
* @param {Function} plugin
* @api private
*/
Socket.prototype.use = function(plugin){
plugin(this);
return this;
};
/**
* Creates a new `Message` and write the `args`.
*
* @param {Array} args
* @return {Buffer}
* @api private
*/
Socket.prototype.pack = function(args){
var msg = new Message(args);
return msg.toBuffer();
};
/**
* Close all open underlying sockets.
*
* @api private
*/
Socket.prototype.closeSockets = function(){
debug('closing %d connections', this.socks.length);
this.socks.forEach(function(sock){
sock.destroy();
});
};
/**
* Close the socket.
*
* Delegates to the server or clients
* based on the socket `type`.
*
* @param {Function} [fn]
* @api public
*/
Socket.prototype.close = function(fn){
debug('closing');
this.closing = true;
this.closeSockets();
if (this.server) this.closeServer(fn);
};
/**
* Close the server.
*
* @param {Function} [fn]
* @api public
*/
Socket.prototype.closeServer = function(fn){
debug('closing server');
this.server.on('close', this.emit.bind(this, 'close'));
this.server.close();
fn && fn();
};
/**
* Return the server address.
*
* @return {Object}
* @api public
*/
Socket.prototype.address = function(){
if (!this.server) return;
var addr = this.server.address();
addr.string = 'tcp://' + addr.address + ':' + addr.port;
return addr;
};
/**
* Remove `sock`.
*
* @param {Socket} sock
* @api private
*/
Socket.prototype.removeSocket = function(sock){
var i = this.socks.indexOf(sock);
if (!~i) return;
debug('remove socket %d', i);
this.socks.splice(i, 1);
};
/**
* Add `sock`.
*
* @param {Socket} sock
* @api private
*/
Socket.prototype.addSocket = function(sock){
var parser = new Parser;
var i = this.socks.push(sock) - 1;
debug('add socket %d', i);
sock.pipe(parser);
parser.on('data', this.onmessage(sock));
};
/**
* Handle `sock` errors.
*
* Emits:
*
* - `error` (err) when the error is not ignored
* - `ignored error` (err) when the error is ignored
* - `socket error` (err) regardless of ignoring
*
* @param {Socket} sock
* @api private
*/
Socket.prototype.handleErrors = function(sock){
var self = this;
sock.on('error', function(err){
debug('error %s', err.code || err.message);
self.emit('socket error', err);
self.removeSocket(sock);
if (!~ignore.indexOf(err.code)) return self.emit('error', err);
debug('ignored %s', err.code);
self.emit('ignored error', err);
});
};
/**
* Handles framed messages emitted from the parser, by
* default it will go ahead and emit the "message" events on
* the socket. However, if the "higher level" socket needs
* to hook into the messages before they are emitted, it
* should override this method and take care of everything
* it self, including emitted the "message" event.
*
* @param {net.Socket} sock
* @return {Function} closure(msg, mulitpart)
* @api private
*/
Socket.prototype.onmessage = function(sock){
var self = this;
return function(buf){
var msg = new Message(buf);
self.emit.apply(self, ['message'].concat(msg.args), sock);
};
};
/**
* Connect to `port` at `host` and invoke `fn()`.
*
* Defaults `host` to localhost.
*
* TODO: needs big cleanup
*
* @param {Number|String} port
* @param {String} host
* @param {Function} fn
* @return {Socket}
* @api public
*/
Socket.prototype.connect = function(port, host, fn){
var self = this;
if ('server' == this.type) throw new Error('cannot connect() after bind()');
if ('function' == typeof host) fn = host, host = undefined;
if ('string' == typeof port) {
port = url.parse(port);
if (port.pathname) {
fn = host;
host = null;
fn = undefined;
port = port.pathname;
} else {
host = port.hostname || '0.0.0.0';
port = parseInt(port.port, 10);
}
} else {
host = host || '0.0.0.0';
}
var max = self.get('retry max timeout');
var sock = new net.Socket;
sock.setNoDelay();
this.type = 'client';
port = port;
this.handleErrors(sock);
sock.on('close', function(){
self.connected = false;
self.removeSocket(sock);
if (self.closing) return self.emit('close');
var retry = self.retry || self.get('retry timeout');
if (retry === 0) return self.emit('close');
setTimeout(function(){
debug('attempting reconnect');
self.emit('reconnect attempt');
sock.destroy();
self.connect(port, host);
self.retry = Math.round(Math.min(max, retry * 1.5));
}, retry);
});
sock.on('connect', function(){
debug('connect');
self.connected = true;
self.addSocket(sock);
self.retry = self.get('retry timeout');
self.emit('connect');
fn && fn();
});
debug('connect attempt %s:%s', host, port);
sock.connect(port, host);
return this;
};
/**
* Handle connection.
*
* @param {Socket} sock
* @api private
*/
Socket.prototype.onconnect = function(sock){
var self = this;
var addr = null;
if (sock.remoteAddress && sock.remotePort)
addr = sock.remoteAddress + ':' + sock.remotePort;
else if (sock.server && sock.server._pipeName)
addr = sock.server._pipeName;
debug('accept %s', addr);
this.addSocket(sock);
this.handleErrors(sock);
this.emit('connect', sock);
sock.on('close', function(){
debug('disconnect %s', addr);
self.emit('disconnect', sock);
self.removeSocket(sock);
});
};
/**
* Bind to `port` at `host` and invoke `fn()`.
*
* Defaults `host` to INADDR_ANY.
*
* Emits:
*
* - `connection` when a client connects
* - `disconnect` when a client disconnects
* - `bind` when bound and listening
*
* @param {Number|String} port
* @param {Function} fn
* @return {Socket}
* @api public
*/
Socket.prototype.bind = function(port, host, fn){
var self = this;
if ('client' == this.type) throw new Error('cannot bind() after connect()');
if ('function' == typeof host) fn = host, host = undefined;
var unixSocket = false;
if ('string' == typeof port) {
port = url.parse(port);
if (port.pathname) {
fn = host;
host = null;
port = port.pathname;
unixSocket = true;
} else {
host = port.hostname || '0.0.0.0';
port = parseInt(port.port, 10);
}
} else {
host = host || '0.0.0.0';
}
this.type = 'server';
this.server = net.createServer(this.onconnect.bind(this));
debug('bind %s:%s', host, port);
this.server.on('listening', this.emit.bind(this, 'bind'));
if (unixSocket) {
// TODO: move out
this.server.on('error', function(e) {
debug('Got error while trying to bind', e.stack || e);
if (e.code == 'EADDRINUSE') {
// Unix file socket and error EADDRINUSE is the case if
// the file socket exists. We check if other processes
// listen on file socket, otherwise it is a stale socket
// that we could reopen
// We try to connect to socket via plain network socket
var clientSocket = new net.Socket();
clientSocket.on('error', function(e2) {
debug('Got sub-error', e2);
if (e2.code == 'ECONNREFUSED' || e2.code == 'ENOENT') {
// No other server listening, so we can delete stale
// socket file and reopen server socket
try {
fs.unlinkSync(port);
} catch(e) {}
self.server.listen(port, host, fn);
}
});
clientSocket.connect({path: port}, function() {
// Connection is possible, so other server is listening
// on this file socket
if (fn) return fn(new Error('Process already listening on socket ' + port));
});
}
else {
try {
fs.unlinkSync(port);
} catch(e) {}
self.server.listen(port, host, fn);
}
});
}
this.server.listen(port, host, fn);
return this;
};

View File

@@ -0,0 +1,92 @@
/**
* Module dependencies.
*/
var Message = require('amp-message');
var SubSocket = require('./sub');
/**
* Expose `SubEmitterSocket`.
*/
module.exports = SubEmitterSocket;
/**
* Initialzie a new `SubEmitterSocket`.
*
* @api private
*/
function SubEmitterSocket() {
this.sock = new SubSocket;
this.sock.onmessage = this.onmessage.bind(this);
this.bind = this.sock.bind.bind(this.sock);
this.connect = this.sock.connect.bind(this.sock);
this.close = this.sock.close.bind(this.sock);
this.listeners = [];
}
/**
* Message handler.
*
* @param {net.Socket} sock
* @return {Function} closure(msg, mulitpart)
* @api private
*/
SubEmitterSocket.prototype.onmessage = function(){
var listeners = this.listeners;
var self = this;
return function(buf){
var msg = new Message(buf);
var topic = msg.shift();
for (var i = 0; i < listeners.length; ++i) {
var listener = listeners[i];
var m = listener.re.exec(topic);
if (!m) continue;
listener.fn.apply(this, m.slice(1).concat(msg.args));
}
}
};
/**
* Subscribe to `event` and invoke the given callback `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {SubEmitterSocket} self
* @api public
*/
SubEmitterSocket.prototype.on = function(event, fn){
var re = this.sock.subscribe(event);
this.listeners.push({
event: event,
re: re,
fn: fn
});
return this;
};
/**
* Unsubscribe with the given `event`.
*
* @param {String} event
* @return {SubEmitterSocket} self
* @api public
*/
SubEmitterSocket.prototype.off = function(event){
for (var i = 0; i < this.listeners.length; ++i) {
if (this.listeners[i].event === event) {
this.sock.unsubscribe(this.listeners[i].re);
this.listeners.splice(i--, 1);
}
}
return this;
};

148
api.hyungi.net/node_modules/pm2-axon/lib/sockets/sub.js generated vendored Normal file
View File

@@ -0,0 +1,148 @@
/**
* Module dependencies.
*/
var debug = require('debug')('axon:sub');
var escape = require('escape-string-regexp');
var Message = require('amp-message');
var Socket = require('./sock');
/**
* Expose `SubSocket`.
*/
module.exports = SubSocket;
/**
* Initialize a new `SubSocket`.
*
* @api private
*/
function SubSocket() {
Socket.call(this);
this.subscriptions = [];
}
/**
* Inherits from `Socket.prototype`.
*/
SubSocket.prototype.__proto__ = Socket.prototype;
/**
* Check if this socket has subscriptions.
*
* @return {Boolean}
* @api public
*/
SubSocket.prototype.hasSubscriptions = function(){
return !! this.subscriptions.length;
};
/**
* Check if any subscriptions match `topic`.
*
* @param {String} topic
* @return {Boolean}
* @api public
*/
SubSocket.prototype.matches = function(topic){
for (var i = 0; i < this.subscriptions.length; ++i) {
if (this.subscriptions[i].test(topic)) {
return true;
}
}
return false;
};
/**
* Message handler.
*
* @param {net.Socket} sock
* @return {Function} closure(msg, mulitpart)
* @api private
*/
SubSocket.prototype.onmessage = function(sock){
var subs = this.hasSubscriptions();
var self = this;
return function(buf){
var msg = new Message(buf);
if (subs) {
var topic = msg.args[0];
if (!self.matches(topic)) return debug('not subscribed to "%s"', topic);
}
self.emit.apply(self, ['message'].concat(msg.args).concat(sock));
};
};
/**
* Subscribe with the given `re`.
*
* @param {RegExp|String} re
* @return {RegExp}
* @api public
*/
SubSocket.prototype.subscribe = function(re){
debug('subscribe to "%s"', re);
this.subscriptions.push(re = toRegExp(re));
return re;
};
/**
* Unsubscribe with the given `re`.
*
* @param {RegExp|String} re
* @api public
*/
SubSocket.prototype.unsubscribe = function(re){
debug('unsubscribe from "%s"', re);
re = toRegExp(re);
for (var i = 0; i < this.subscriptions.length; ++i) {
if (this.subscriptions[i].toString() === re.toString()) {
this.subscriptions.splice(i--, 1);
}
}
};
/**
* Clear current subscriptions.
*
* @api public
*/
SubSocket.prototype.clearSubscriptions = function(){
this.subscriptions = [];
};
/**
* Subscribers should not send messages.
*/
SubSocket.prototype.send = function(){
throw new Error('subscribers cannot send messages');
};
/**
* Convert `str` to a `RegExp`.
*
* @param {String} str
* @return {RegExp}
* @api private
*/
function toRegExp(str) {
if (str instanceof RegExp) return str;
str = escape(str);
str = str.replace(/\\\*/g, '(.+)');
return new RegExp('^' + str + '$');
}

19
api.hyungi.net/node_modules/pm2-axon/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/**
* Slice helper.
*
* @api private
* @param {Arguments} args
* @return {Array}
*/
exports.slice = function(args){
var len = args.length;
var ret = new Array(len);
for (var i = 0; i < len; i++) {
ret[i] = args[i];
}
return ret;
};