This repository has been archived by the owner on Aug 23, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 37
Make switch a state machine #278
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
c47ab13
feat: add basic state machine functionality to switch
jacobheun a97c386
fix: linting
jacobheun b4d1602
refactor: move connection.js to connection-manager.js
jacobheun 41e4a88
feat: add outgoing connection state machine
jacobheun 5848e6d
feat: functioning incoming connection fsm
jacobheun 45ae65b
fix: linting
jacobheun 78203fd
fix: stats
jacobheun 0b9f5f1
docs: remove notes
jacobheun ef92ee2
test: bump circuit shutdown timeout
jacobheun 4b62917
fix: node 8 support
jacobheun 7ab2151
feat: add class-is support for connections
jacobheun 674d55c
refactor: clean up some logic and make inc muxed conns FSMs
jacobheun f4a1806
fix: cleanup todos, logic and event handlers
jacobheun dd12ad1
refactor: clean up logs
jacobheun 56ea400
feat: add dialFSM to the switch
jacobheun 2e1f7b5
refactor: rename test file
jacobheun 75f1370
feat: add better support for closing connections
jacobheun 0ee8157
test: add tests for some uncovered lines
jacobheun d921c2d
refactor: do some cleanup
jacobheun 6351365
feat: add additional fsm user support
jacobheun 3d469d0
feat: add warning emitter for muxer upgrade failed
jacobheun 662a58f
refactor: cleanup and add some tests
jacobheun 730c2b6
test: add test for failed muxer upgrade
jacobheun 6dd8f39
test: add more error state tests for connectionfsm
jacobheun a2e995e
docs: update readme
jacobheun ef85443
docs: fix readme link
jacobheun 8ff0375
docs: clean up readme and jsdocs
jacobheun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
'use strict' | ||
|
||
const EventEmitter = require('events').EventEmitter | ||
const debug = require('debug') | ||
const withIs = require('class-is') | ||
|
||
class BaseConnection extends EventEmitter { | ||
constructor ({ _switch, name }) { | ||
super() | ||
|
||
this.switch = _switch | ||
this.ourPeerInfo = this.switch._peerInfo | ||
this.log = debug(`libp2p:conn:${name}`) | ||
} | ||
|
||
/** | ||
* Gets the current state of the connection | ||
* | ||
* @returns {string} The current state of the connection | ||
*/ | ||
getState () { | ||
return this._state._state | ||
} | ||
|
||
/** | ||
* Puts the state into encrypting mode | ||
* | ||
* @returns {void} | ||
*/ | ||
encrypt () { | ||
this._state('encrypt') | ||
} | ||
|
||
/** | ||
* Puts the state into privatizing mode | ||
* | ||
* @returns {void} | ||
*/ | ||
protect () { | ||
this._state('privatize') | ||
} | ||
|
||
/** | ||
* Puts the state into muxing mode | ||
* | ||
* @returns {void} | ||
*/ | ||
upgrade () { | ||
this._state('upgrade') | ||
} | ||
|
||
/** | ||
* Event handler for disconnected. | ||
* | ||
* @fires BaseConnection#close | ||
* @returns {void} | ||
*/ | ||
_onDisconnected () { | ||
this.log(`disconnected from ${this.theirB58Id}`) | ||
this.emit('close') | ||
this.removeAllListeners() | ||
} | ||
|
||
/** | ||
* Event handler for privatized | ||
* | ||
* @fires BaseConnection#private | ||
* @returns {void} | ||
*/ | ||
_onPrivatized () { | ||
this.log(`successfully privatized incoming connection`) | ||
this.emit('private', this.conn) | ||
} | ||
|
||
/** | ||
* Wraps this.conn with the Switch.protector for private connections | ||
* | ||
* @private | ||
* @fires ConnectionFSM#error | ||
* @returns {void} | ||
*/ | ||
_onPrivatizing () { | ||
if (!this.switch.protector) { | ||
return this._state('done') | ||
} | ||
|
||
this.conn = this.switch.protector.protect(this.conn, (err) => { | ||
if (err) { | ||
this.emit('error', err) | ||
return this._state('disconnect') | ||
} | ||
|
||
this.log(`successfully privatized conn to ${this.theirB58Id}`) | ||
this.conn.setPeerInfo(this.theirPeerInfo) | ||
this._state('done') | ||
}) | ||
} | ||
} | ||
|
||
module.exports = withIs(BaseConnection, { | ||
className: 'BaseConnection', | ||
symbolName: 'libp2p-switch/BaseConnection' | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
'use strict' | ||
|
||
const debug = require('debug') | ||
const IncomingConnection = require('./incoming') | ||
const observeConn = require('../observe-connection') | ||
|
||
function listener (_switch) { | ||
const log = debug(`libp2p:switch:listener`) | ||
|
||
/** | ||
* Takes a transport key and returns a connection handler function | ||
* | ||
* @param {string} transportKey The key of the transport to handle connections for | ||
* @param {function} handler A custom handler to use | ||
* @returns {function(Connection)} A connection handler function | ||
*/ | ||
return (transportKey, handler) => { | ||
/** | ||
* Takes a base connection and manages listening behavior | ||
* | ||
* @param {Connection} conn The connection to manage | ||
* @returns {void} | ||
*/ | ||
return (conn) => { | ||
// Add a transport level observer, if needed | ||
const connection = transportKey ? observeConn(transportKey, null, conn, _switch.observer) : conn | ||
|
||
log('received incoming connection') | ||
const connFSM = new IncomingConnection({ connection, _switch, transportKey }) | ||
|
||
connFSM.once('error', (err) => log(err)) | ||
connFSM.once('private', (_conn) => { | ||
// Use the custom handler, if it was provided | ||
if (handler) { | ||
return handler(_conn) | ||
} | ||
connFSM.encrypt() | ||
}) | ||
connFSM.once('encrypted', () => connFSM.upgrade()) | ||
|
||
connFSM.protect() | ||
} | ||
} | ||
} | ||
|
||
module.exports = listener |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better just mimic js-libp2p and do dial and dialProtocol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@diasdavid are you suggesting to add
dialProtocol
in addition to the newdialFSM
or as a naming replacement? I think havingdial
handle calls with and without a protocol is reasonable overloading. Replacing it wouldn't be good as it has a different callback footprint to give users access to the ConnectionFSM for finer control/handling.I've exposed the same
dialFSM
method in the libp2p branchThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to block this PR for this. What I mean is that given that libp2p (the module) is just an extension to the libp2p-switch (the dialing machine) that adds it other features, it would be cool if they both expose the same dialing/hangup APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. Ideally I'd like to deprecate
dialProtocol
in libp2p and just usedial
. Having both feel unnecessary. I'll propose the change in an issue there and ifdialProtocol
ends up staying we can add that in here.