Socket
Socket
Sign inDemoInstall

sneeze

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sneeze - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

5

package.json
{
"name": "sneeze",
"version": "0.5.0",
"version": "0.6.0",
"description": "Easily join SWIM networks",
"main": "sneeze.js",
"scripts": {
"test": "lab -P test -v -t",
"test": "lab -P test -v -t 90 -r console -I Reflect",
"test-cov-html": "lab -P test -r html -o coverage.html"

@@ -28,2 +28,3 @@ },

"lodash": "4.5.0",
"optioner": "0.6.0",
"swim": "0.3.0"

@@ -30,0 +31,0 @@ },

11

README.md
# sneeze
Easily join SWIM networks. See http://www.cs.cornell.edu/~asdas/research/dsn02-SWIM.pdf.
Easily join SWIM networks. See
http://www.cs.cornell.edu/~asdas/research/dsn02-SWIM.pdf.
This module is used by [seneca-mesh](github.com/rjrodger/seneca-mesh)
to provide zero-configuration service discovery.
## Quick Example
The *base* node serves as the well-known starting point. As other
nodes join and leave all nodes eventually learn about them
nodes (A and B) join and leave. All nodes eventually learn about them.

@@ -28,2 +32,5 @@ ```js

## Questions?

@@ -30,0 +37,0 @@

@@ -13,4 +13,27 @@ /*

var Swim = require('swim')
var Optioner = require('optioner')
var Joi = Optioner.Joi
var DEFAULT_HOST = module.exports.DEFAULT_HOST = '127.0.0.1'
var DEFAULT_PORT = module.exports.DEFAULT_PORT = 39999
var optioner = Optioner({
isbase: false,
host: DEFAULT_HOST,
bases: Joi.array().default([DEFAULT_HOST+':'+DEFAULT_PORT]),
retry_attempts: 22,
retry_min: 111,
retry_max: 555,
silent: true,
log: null,
tag: null,
port: null,
identifier: null,
// [include,exclude]
port_range: [40000,50000]
})
module.exports = function (options) {

@@ -23,8 +46,8 @@ return new Sneeze( options )

var self = this
var tick = 0
/*
options = _.defaultsDeep(options,{
isbase: false,
host: '127.0.0.1',
bases: ['127.0.0.1:39999'],
host: DEFAULT_HOST,
bases: [DEFAULT_HOST+':'+DEFAULT_PORT],
retry_attempts: 22,

@@ -35,172 +58,189 @@ retry_min: 111,

log: null,
tag: null
tag: null,
port: null,
// [include,exclude]
port_range: [40000,50000]
})
*/
if( !options.silent && null == options.log ) {
options.log = function () {
console.log.apply(null,_.flatten(['SNEEZE',tick,arguments]))
}
}
optioner(options, function(err, options) {
if (err) throw err
var log = options.log || _.noop
var isbase = !!options.isbase
if( options.isbase ) {
options.port = null == options.port ? 39999 : options.port
}
else {
options.port = options.port || function() {
return 40000 + Math.floor((10000*Math.random()))
}
}
self.log =
!!options.silent ? _.noop :
_.isFunction(options.log) ? options.log :
function () {
console.log.apply(null,_.flatten(
['SNEEZE', (''+Date.now()).substring(8), arguments]))
}
var swim
var members = {}
self.makeport = _.isFunction(options.port) ? options.port :
function() {
var port = parseInt(options.port)
var pr = options.port_range
this.join = function( meta ) {
meta = meta || {}
port = !isNaN(port) ? port :
isbase ? DEFAULT_PORT :
pr[0] +
Math.floor(((pr[1]-pr[0])*Math.random()))
var attempts = 0, max_attempts = options.retry_attempts, joined = false
return port
}
function join() {
var port = (_.isFunction(options.port) ? options.port() : options.port )
var host = options.host + ':' + port
var incarnation = Date.now()
var swim
var members = {}
self.id = meta.identifier$ = null == options.identifier ?
host+'~'+incarnation+'~'+Math.random() : options.identifier
self.join = function( meta ) {
meta = meta || {}
meta.tag$ = options.tag
var attempts = 0, max_attempts = options.retry_attempts, joined = false
log('joining',attempts,host,meta.identifier$,meta.tag$)
function join() {
//var port = (_.isFunction(options.port) ? options.port() : options.port )
var port = self.makeport()
var host = options.host + ':' + port
var incarnation = Date.now()
var swim_opts = _.defaultsDeep(options.swim,{
codec: 'msgpack',
disseminationFactor: 22,
interval: 111,
joinTimeout: 777,
pingTimeout: 444,
pingReqTimeout: 333,
pingReqGroupSize: 7,
udp: {maxDgramSize: 2048},
})
self.id = meta.identifier$ = null == options.identifier ?
host+'~'+incarnation+'~'+Math.random() : options.identifier
swim_opts.local = {
host: host,
meta: meta,
incarnation: incarnation,
}
meta.tag$ = options.tag
var bases = _.compact(_.clone(options.bases))
if( options.isbase ) {
_.remove(bases,function(r) { return r === host })
}
self.log('joining',attempts,host,meta.identifier$,meta.tag$)
swim = new Swim(swim_opts)
var swim_opts = _.defaultsDeep(options.swim,{
codec: 'msgpack',
disseminationFactor: 22,
interval: 111,
joinTimeout: 777,
pingTimeout: 444,
pingReqTimeout: 333,
pingReqGroupSize: 7,
udp: {maxDgramSize: 2048},
})
swim.net.on('error', function(err) {
if (err && !joined && attempts < max_attempts) {
attempts++
swim_opts.local = {
host: host,
meta: meta,
incarnation: incarnation,
}
var wait = options.retry_min +
Math.floor(Math.random() * (options.retry_max-options.retry_min))
setTimeout(join, wait)
return
var bases = _.compact(_.clone(options.bases))
if( isbase ) {
_.remove(bases,function(r) { return r === host })
}
else if( err ) {
self.emit('error',err)
return
}
})
swim.bootstrap(bases, function onBootstrap(err) {
if (!options.isbase && err && !joined && attempts < max_attempts) {
attempts++
swim = new Swim(swim_opts)
var wait = options.retry_min +
Math.floor(Math.random() * (options.retry_max-options.retry_min))
swim.net.on('error', function(err) {
if (err && !joined && attempts < max_attempts) {
attempts++
setTimeout(join, wait)
return
}
else if( err ) {
// first base node will see a JoinFailedError as there is
// nobody else out there
if( !options.isbase || 'JoinFailedError' !== err.name ) {
var wait = options.retry_min +
Math.floor(Math.random() * (options.retry_max-options.retry_min))
setTimeout(join, wait)
return
}
else if( err ) {
self.emit('error',err)
return
}
}
})
joined = true
swim.bootstrap(bases, function onBootstrap(err) {
if (!isbase && err && !joined && attempts < max_attempts) {
attempts++
_.each( swim.members(), updateinfo )
var wait = options.retry_min +
Math.floor(Math.random() * (options.retry_max-options.retry_min))
swim.on(Swim.EventType.Update, function onUpdate(info) {
updateinfo(info)
})
setTimeout(join, wait)
return
}
else if( err ) {
// first base node will see a JoinFailedError as there is
// nobody else out there
if( !isbase || 'JoinFailedError' !== err.name ) {
self.emit('error',err)
return
}
}
swim.on(Swim.EventType.Change, function onChange(info) {
updateinfo(info)
joined = true
_.each( swim.members(), updateinfo )
swim.on(Swim.EventType.Update, function onUpdate(info) {
updateinfo(info)
})
swim.on(Swim.EventType.Change, function onChange(info) {
updateinfo(info)
})
self.emit('ready')
})
self.emit('ready')
})
function updateinfo( m ) {
if (!m.meta) {
return
}
function updateinfo( m ) {
if (!m.meta) {
return
}
if( null != meta.tag$ && m.meta.tag$ !== meta.tag$ ) {
return
}
if( null != meta.tag$ && m.meta.tag$ !== meta.tag$ ) {
return
}
if( m.meta.identifier$ === meta.identifier$ ) {
return
}
if( m.meta.identifier$ === meta.identifier$ ) {
return
}
if( 0 === m.state ) {
add_node( host, m.meta )
}
if( 0 === m.state ) {
add_node( host, m.meta )
// Note: trigger happy
else if( 2 === m.state ) {
remove_node( host, m.meta )
}
}
}
// Note: trigger happy
else if( 2 === m.state ) {
remove_node( host, m.meta )
}
}
join()
}
join()
}
self.members = function() {
return _.clone( members )
}
self.members = function() {
return _.clone( members )
}
self.leave = function() {
swim && swim.leave()
}
self.leave = function() {
swim && swim.leave()
}
function add_node( host, meta ) {
self.log('add', host, meta.identifier$, meta.tag$, meta)
members[meta.identifier$] = meta
self.emit('add', meta)
}
function add_node( host, meta ) {
log('add', host, meta.identifier$, meta.tag$, meta)
members[meta.identifier$] = meta
self.emit('add', meta)
}
function remove_node( host, meta ) {
self.log('remove', host, meta.identifier$, meta.tag$, meta)
delete members[meta.identifier$]
self.emit('remove', meta)
}
function remove_node( host, meta ) {
log('remove', host, meta.identifier$, meta.tag$, meta)
delete members[meta.identifier$]
self.emit('remove', meta)
}
self.on('error',function(err){
self.log('ERROR',err)
})
self.on('error',function(err){
log('ERROR QQQ',err)
})
}
Util.inherits(Sneeze, Events.EventEmitter)

@@ -5,12 +5,14 @@ // quick start with single base:

// multi-base network:
// $ node base.js b0 39000 127.0.0.1:39000,127.0.0.1:39001
// $ node base.js b1 39001 127.0.0.1:39000,127.0.0.1:39001
// $ node base.js b0 127.0.0.1 39000 127.0.0.1:39000,127.0.0.1:39001
// $ node base.js b1 127.0.0.1 39001 127.0.0.1:39000,127.0.0.1:39001
var NAME = process.env.NAME || process.argv[2] || 'b0'
var PORT = process.env.PORT || process.argv[3] || 39999
var BASES = (process.env.BASES || process.argv[4] || '').split(',')
var HOST = process.env.HOST || process.argv[3] || '127.0.0.1'
var PORT = process.env.PORT || process.argv[4] || 39000
var BASES = (process.env.BASES || process.argv[5] || '127.0.0.1:39000').split(',')
require('..')({
isbase: true,
silent: true,
silent: false,
host: HOST,
port: PORT,

@@ -17,0 +19,0 @@ bases: BASES

@@ -5,14 +5,16 @@ // quick start with single base:

// multi-base network:
// $ node member.js m0 127.0.0.1:39000,127.0.0.1:39001
// $ node member.js m1 127.0.0.1:39000,127.0.0.1:39001
// $ node member.js m2 127.0.0.1:39000,127.0.0.1:39001
// $ node member.js m0 127.0.0.1 127.0.0.1:39000,127.0.0.1:39001
// $ node member.js m1 127.0.0.1 127.0.0.1:39000,127.0.0.1:39001
// $ node member.js m2 127.0.0.1 127.0.0.1:39000,127.0.0.1:39001
// ...
var NAME = process.env.NAME || process.argv[2] || 'm0'
var BASES = (process.env.BASES || process.argv[3] || '127.0.0.1:39999').split(',')
var HOST = process.env.HOST || process.argv[3] || '127.0.0.1'
var BASES = (process.env.BASES || process.argv[4] || '127.0.0.1:39000').split(',')
require('..')({
bases: BASES,
bases: BASES,
host: HOST,
silent: false
})
.join({name: NAME})

@@ -56,2 +56,48 @@ 'use strict'

it('methods', function (done) {
var s0 = Sneeze()
s0.log('vanish')
for( var i = 0; i < 22222; ++i) {
var p = s0.makeport()
expect(40000<=p && p<50000).to.equal(true)
}
s0.leave()
var log = []
var s1 = Sneeze({
port: 33333,
silent: false,
log: function () {
log.push(Array.prototype.slice.call(arguments))
}
})
s1.log('hello1')
expect(s1.makeport()).to.equal(33333)
expect(log).to.deep.equal([['hello1']])
log = []
var origwrite = process.stdout.write
process.stdout.write = function() {
log.push(arguments)
}
var s2 = Sneeze({
port: function() {
return 22222
},
silent: false
})
s2.log('hello2')
process.stdout.write = origwrite
expect(s2.makeport()).to.equal(22222)
expect(log[0][0]).to.contain('hello2')
done()
})
it('collision', { parallel: false, timeout:5555 }, function (done) {

@@ -199,3 +245,3 @@ var base = Sneeze({isbase: true})

isbase: true, silent: silent, identifier:'b0',
host:'127.0.0.1',port:39000,
host:'127.0.0.1', port:39000,
bases:bases

@@ -202,0 +248,0 @@ })

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc