ssb-conn-hub
Advanced tools
Comparing version 0.0.3 to 0.0.4
@@ -6,2 +6,3 @@ import { ConnectionData as Data, Address } from './types'; | ||
private readonly _notify; | ||
private _closed; | ||
private readonly _connectRetries; | ||
@@ -23,3 +24,4 @@ constructor(server: any); | ||
listen(): any; | ||
close(): void; | ||
} | ||
export = ConnHub; |
104
lib/index.js
@@ -100,3 +100,42 @@ "use strict"; | ||
function ConnHub(server) { | ||
var _this = this; | ||
this._onRpcConnect = function (rpc, isClient) { | ||
if (!_this._server.ready() && rpc.id !== _this._server.id) | ||
return rpc.close(); | ||
if (rpc.id === _this._server.id) | ||
return; | ||
var peer = _this._getPeerByKey(rpc.id); | ||
if (!peer) { | ||
rpc._connectRetries = rpc._connectRetries || 0; | ||
if (isClient && rpc._connectRetries < 4) { | ||
setTimeout(function () { | ||
_this._onRpcConnect(rpc, isClient); | ||
}, 200); | ||
rpc._connectRetries += 1; | ||
} | ||
else { | ||
debug('peer %s initiated an RPC connection with us', rpc.id); | ||
} | ||
return; | ||
} | ||
var _a = __read(peer, 2), address = _a[0], data = _a[1]; | ||
var key = data.key; | ||
var state = 'connected'; | ||
var disconnect = function (cb) { return rpc.close(true, cb); }; | ||
_this._setPeer(address, { state: state, key: key, disconnect: disconnect }); | ||
debug('connected to %s', address); | ||
_this._notify({ | ||
type: state, | ||
address: address, | ||
key: key, | ||
details: { rpc: rpc, isClient: isClient }, | ||
}); | ||
rpc.on('closed', function () { | ||
_this._peers.delete(address); | ||
debug('disconnected from %s', address); | ||
_this._notify({ type: 'disconnected', address: address, key: key }); | ||
}); | ||
}; | ||
this._server = server; | ||
this._closed = false; | ||
this._connectRetries = new Set(); | ||
@@ -108,3 +147,3 @@ this._peers = new Map(); | ||
ConnHub.prototype._init = function () { | ||
this._server.on('rpc:connect', this._onRpcConnect.bind(this)); | ||
this._server.addListener('rpc:connect', this._onRpcConnect); | ||
}; | ||
@@ -146,40 +185,2 @@ ConnHub.prototype._setPeer = function (address, data) { | ||
}; | ||
ConnHub.prototype._onRpcConnect = function (rpc, isClient) { | ||
var _this = this; | ||
if (!this._server.ready() && rpc.id !== this._server.id) | ||
return rpc.close(); | ||
if (rpc.id === this._server.id) | ||
return; | ||
var peer = this._getPeerByKey(rpc.id); | ||
if (!peer) { | ||
rpc._connectRetries = rpc._connectRetries || 0; | ||
if (isClient && rpc._connectRetries < 4) { | ||
setTimeout(function () { | ||
_this._onRpcConnect(rpc, isClient); | ||
}, 200); | ||
rpc._connectRetries += 1; | ||
} | ||
else { | ||
debug('RPC client %s connected to us, but not via conn-hub', rpc.id); | ||
} | ||
return; | ||
} | ||
var _a = __read(peer, 2), address = _a[0], data = _a[1]; | ||
var key = data.key; | ||
var state = 'connected'; | ||
var disconnect = function (cb) { return rpc.close(true, cb); }; | ||
this._setPeer(address, { state: state, key: key, disconnect: disconnect }); | ||
debug('connected to %s', address); | ||
this._notify({ | ||
type: state, | ||
address: address, | ||
key: key, | ||
details: { rpc: rpc, isClient: isClient }, | ||
}); | ||
rpc.on('closed', function () { | ||
_this._peers.delete(address); | ||
debug('disconnected from %s', address); | ||
_this._notify({ type: 'disconnected', address: address, key: key }); | ||
}); | ||
}; | ||
ConnHub.prototype.connect = function (address) { | ||
@@ -191,2 +192,5 @@ return __awaiter(this, void 0, void 0, function () { | ||
case 0: | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
@@ -245,2 +249,5 @@ throw new Error('The given address is not a valid multiserver-address'); | ||
case 0: | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
@@ -289,2 +296,5 @@ throw new Error('The given address is not a valid multiserver-address'); | ||
var e_2, _a; | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
for (var id in this._server.peers) { | ||
@@ -309,5 +319,11 @@ if (id !== this._server.id) { | ||
ConnHub.prototype.entries = function () { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
return this._peers.entries(); | ||
}; | ||
ConnHub.prototype.getState = function (address) { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
@@ -321,6 +337,16 @@ throw new Error('The given address is not a valid multiserver-address'); | ||
ConnHub.prototype.listen = function () { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
return this._notify.listen(); | ||
}; | ||
ConnHub.prototype.close = function () { | ||
this._server.removeListener('rpc:connect', this._onRpcConnect); | ||
this._closed = true; | ||
this._peers.clear(); | ||
this._notify.end(); | ||
debug('closed the ConnHub instance'); | ||
}; | ||
return ConnHub; | ||
}()); | ||
module.exports = ConnHub; |
{ | ||
"name": "ssb-conn-hub", | ||
"description": "Module that manages active connections to SSB peers", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"homepage": "https://github.com/staltz/ssb-conn-hub", | ||
@@ -34,2 +34,2 @@ "main": "lib/index.js", | ||
"license": "MIT" | ||
} | ||
} |
# ssb-conn-hub | ||
Module that manages active connections to peers. For use with the SSB CONN family of modules. | ||
Module that manages active connections to peers. For use with the SSB CONN family of modules. See also [ssb-conn-db](https://github.com/staltz/ssb-conn-db). | ||
*Visual metaphor: a network switch managing connections to other peers, capable of starting or stopping connections.* | ||
![hub.png](./hub.png) | ||
## Usage | ||
@@ -51,2 +55,3 @@ | ||
* `connHub.getState(address)`: returns undefined if the peer for that address is disconnected, otherwise returns one of `'connecting'`, `'connected'`, or `'disconnecting'` | ||
* `connHub.close()`: terminates any used resources and listeners, in preparation to destroy this instance. | ||
@@ -53,0 +58,0 @@ ## License |
import {ConnectionData as Data, ListenEvent, Address} from './types'; | ||
import run = require('promisify-tuple'); | ||
import {EventEmitter} from 'events'; | ||
const Notify = require('pull-notify'); | ||
@@ -32,2 +33,3 @@ const msAddress = require('multiserver-address'); | ||
private readonly _notify: any; | ||
private _closed: boolean; | ||
@@ -41,2 +43,3 @@ /** | ||
this._server = server; | ||
this._closed = false; | ||
this._connectRetries = new Set<Address>(); | ||
@@ -49,3 +52,6 @@ this._peers = new Map<Address, Data>(); | ||
private _init() { | ||
this._server.on('rpc:connect', this._onRpcConnect.bind(this)); | ||
(this._server as EventEmitter).addListener( | ||
'rpc:connect', | ||
this._onRpcConnect, | ||
); | ||
} | ||
@@ -75,3 +81,3 @@ | ||
private _onRpcConnect(rpc: any, isClient: boolean) { | ||
private _onRpcConnect = (rpc: any, isClient: boolean) => { | ||
// If we're not ready, close this connection immediately: | ||
@@ -95,3 +101,3 @@ if (!this._server.ready() && rpc.id !== this._server.id) return rpc.close(); | ||
} else { | ||
debug('RPC client %s connected to us, but not via conn-hub', rpc.id); | ||
debug('peer %s initiated an RPC connection with us', rpc.id); | ||
} | ||
@@ -120,3 +126,3 @@ return; | ||
}); | ||
} | ||
}; | ||
@@ -128,2 +134,5 @@ /////////////// | ||
public async connect(address: Address): Promise<false | object> { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
@@ -176,2 +185,5 @@ throw new Error('The given address is not a valid multiserver-address'); | ||
public async disconnect(address: Address): Promise<boolean> { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
@@ -222,2 +234,5 @@ throw new Error('The given address is not a valid multiserver-address'); | ||
public reset() { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
for (var id in this._server.peers) { | ||
@@ -233,2 +248,5 @@ if (id !== this._server.id) { | ||
public entries() { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
return this._peers.entries(); | ||
@@ -238,2 +256,5 @@ } | ||
public getState(address: Address): Data['state'] | undefined { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
@@ -249,8 +270,21 @@ throw new Error('The given address is not a valid multiserver-address'); | ||
// TODO document all the possible types of events | ||
public listen() { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
return this._notify.listen(); | ||
} | ||
public close() { | ||
(this._server as EventEmitter).removeListener( | ||
'rpc:connect', | ||
this._onRpcConnect, | ||
); | ||
this._closed = true; | ||
this._peers.clear(); | ||
this._notify.end(); | ||
debug('closed the ConnHub instance'); | ||
} | ||
} | ||
export = ConnHub; |
@@ -79,2 +79,29 @@ const tape = require('tape'); | ||
tape('after close(), nothing works', function(t) { | ||
t.plan(3); | ||
const connHub = new ConnHub(ssbServer); | ||
connHub.disconnect(TEST_ADDR).then( | ||
result => { | ||
t.strictEquals(result, false, 'Resolves with false'); | ||
connHub.close(); | ||
t.pass('close() succeeds silently'); | ||
t.throws( | ||
() => { | ||
const x = connHub.entries(); | ||
}, | ||
/instance is closed/, | ||
'entries() throws an error after close()', | ||
); | ||
t.end(); | ||
}, | ||
_err => { | ||
t.fail('The disconnection should not happen'); | ||
}, | ||
); | ||
}); | ||
tape('teardown', t => { | ||
@@ -81,0 +108,0 @@ ssbServer.close(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
110555
14
803
60