Skip to content

Commit

Permalink
refactor: ping (#505)
Browse files Browse the repository at this point in the history
* refactor: ping

* chore: ping is now a function

* chore: address review
  • Loading branch information
vasco-santos authored and jacobheun committed Dec 10, 2019
1 parent 1cf3198 commit 88e5698
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 174 deletions.
26 changes: 26 additions & 0 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* [`hangUp`](#hangUp)
* [`handle`](#handle)
* [`unhandle`](#unhandle)
* [`ping`](#ping)
* [`peerRouting.findPeer`](#peerRouting.findPeer)
* [`contentRouting.findProviders`](#contentRouting.findProviders)
* [`contentRouting.provide`](#contentRouting.provide)
Expand Down Expand Up @@ -307,6 +308,31 @@ Unregisters all handlers with the given protocols
libp2p.unhandle(['/echo/1.0.0'])
```

### ping

Pings a given peer and get the operation's latency.

`libp2p.ping(peer)`

#### Parameters

| Name | Type | Description |
|------|------|-------------|
| peer | `PeerInfo|PeerId|Multiaddr|string` | peer to ping |

#### Returns

| Type | Description |
|------|-------------|
| `Promise<number>` | Latency of the operation in ms |

#### Example

```js
// ...
const latency = await libp2p.ping(otherPeerId)
```

### peerRouting.findPeer

Iterates over all peer routers in series to find the given peer. If the DHT is enabled, it will be tried first.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"err-code": "^1.1.2",
"hashlru": "^2.3.0",
"it-all": "^1.0.1",
"it-buffer": "^0.1.1",
"it-handshake": "^1.0.1",
"it-length-prefixed": "^3.0.0",
"it-pipe": "^1.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/identify/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const { collect, take } = require('streaming-iterables')
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const multiaddr = require('multiaddr')
const { toBuffer } = require('../util')
const { toBuffer } = require('it-buffer')

const Message = require('./message')

Expand Down
27 changes: 16 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const TransportManager = require('./transport-manager')
const Upgrader = require('./upgrader')
const PeerStore = require('./peer-store')
const Registrar = require('./registrar')
const ping = require('./ping')
const {
IdentifyService,
multicodecs: IDENTIFY_PROTOCOLS
Expand Down Expand Up @@ -148,6 +149,9 @@ class Libp2p extends EventEmitter {
this.peerRouting = peerRouting(this)
this.contentRouting = contentRouting(this)

// Mount default protocols
ping.mount(this)

this._onDiscoveryPeer = this._onDiscoveryPeer.bind(this)
}

Expand Down Expand Up @@ -203,6 +207,8 @@ class Libp2p extends EventEmitter {

await this.transportManager.close()
await this.registrar.close()

ping.unmount(this)
} catch (err) {
if (err) {
log.error(err)
Expand Down Expand Up @@ -280,17 +286,16 @@ class Libp2p extends EventEmitter {
)
}

// TODO: Update ping
// /**
// * Pings the provided peer
// *
// * @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to ping
// * @returns {Promise<Ping>}
// */
// ping (peer) {
// const peerInfo = await getPeerInfoRemote(peer, this)
// return new Ping(this._switch, peerInfo)
// }
/**
* Pings the given peer
* @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to ping
* @returns {Promise<number>}
*/
async ping (peer) {
const peerInfo = await getPeerInfo(peer, this.peerStore)

return ping(this, peerInfo)
}

/**
* Registers the `handler` for each protocol
Expand Down
13 changes: 4 additions & 9 deletions src/ping/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@ libp2p-ping JavaScript Implementation
## Usage

```javascript
var Ping = require('libp2p-ping')
var Ping = require('libp2p/src/ping')

Ping.mount(swarm) // Enable this peer to echo Ping requests
Ping.mount(libp2p) // Enable this peer to echo Ping requests

var p = new Ping(swarm, peerDst) // Ping peerDst, peerDst must be a peer-info object
const latency = await Ping(libp2p, peerDst)

p.on('ping', function (time) {
console.log(time + 'ms')
p.stop() // stop sending pings
})

p.start()
Ping.unmount(libp2p)
```
50 changes: 0 additions & 50 deletions src/ping/handler.js

This file was deleted.

63 changes: 59 additions & 4 deletions src/ping/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,62 @@
'use strict'

const handler = require('./handler')
const debug = require('debug')
const log = debug('libp2p-ping')
log.error = debug('libp2p-ping:error')
const errCode = require('err-code')

exports = module.exports = require('./ping')
exports.mount = handler.mount
exports.unmount = handler.unmount
const crypto = require('libp2p-crypto')
const pipe = require('it-pipe')
const { toBuffer } = require('it-buffer')
const { collect } = require('streaming-iterables')

const { PROTOCOL, PING_LENGTH } = require('./constants')

/**
* Ping a given peer and wait for its response, getting the operation latency.
* @param {Libp2p} node
* @param {PeerInfo} peer
* @returns {Promise<Number>}
*/
async function ping (node, peer) {
log('dialing %s to %s', PROTOCOL, peer.id.toB58String())

const { stream } = await node.dialProtocol(peer, PROTOCOL)

const start = new Date()
const data = crypto.randomBytes(PING_LENGTH)

const [result] = await pipe(
[data],
stream,
toBuffer,
collect
)
const end = Date.now()

if (!data.equals(result)) {
throw errCode(new Error('Received wrong ping ack'), 'ERR_WRONG_PING_ACK')
}

return end - start
}

/**
* Subscribe ping protocol handler.
* @param {Libp2p} node
*/
function mount (node) {
node.handle(PROTOCOL, ({ stream }) => pipe(stream, stream))
}

/**
* Unsubscribe ping protocol handler.
* @param {Libp2p} node
*/
function unmount (node) {
node.unhandle(PROTOCOL)
}

exports = module.exports = ping
exports.mount = mount
exports.unmount = unmount
83 changes: 0 additions & 83 deletions src/ping/ping.js

This file was deleted.

16 changes: 0 additions & 16 deletions src/util/index.js

This file was deleted.

35 changes: 35 additions & 0 deletions test/core/ping.node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict'
/* eslint-env mocha */

const chai = require('chai')
chai.use(require('dirty-chai'))
const { expect } = chai

const pTimes = require('p-times')

const peerUtils = require('../utils/creators/peer')
const baseOptions = require('../utils/base-options')

describe('ping', () => {
let nodes

beforeEach(async () => {
nodes = await peerUtils.createPeer({
number: 2,
config: baseOptions
})
})

it('ping once from peer0 to peer1', async () => {
const latency = await nodes[0].ping(nodes[1].peerInfo)

expect(latency).to.be.a('Number')
})

it('ping several times for getting an average', async () => {
const latencies = await pTimes(5, () => nodes[1].ping(nodes[0].peerInfo))

const averageLatency = latencies.reduce((p, c) => p + c, 0) / latencies.length
expect(averageLatency).to.be.a('Number')
})
})

0 comments on commit 88e5698

Please sign in to comment.