Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

feat: Ping #1342

Merged
merged 19 commits into from
May 28, 2018
Merged

feat: Ping #1342

merged 19 commits into from
May 28, 2018

Conversation

daviddias
Copy link
Member

@daviddias daviddias commented May 8, 2018

The long time coming promised API :)

Based on the work @JGAntunes, @vasco-santos and @melvin0008

ref: #1299 & #1202

depends on ipfs-inactive/js-ipfs-http-client#768

depends on ipfs/js-ipfsd-ctl#256

@ghost ghost assigned daviddias May 8, 2018
@ghost ghost added the status/in-progress In progress label May 8, 2018
@daviddias daviddias mentioned this pull request May 8, 2018
30 tasks
@daviddias
Copy link
Member Author

@JGAntunes got the following error running the tests:

Debug: internal, implementation, error
    AssertionError: expected 400 to equal 200
    at api.inject (/Users/imp/code/js-ipfs/test/http-api/inject/ping.js:44:35)
    at Shot.inject (/Users/imp/code/js-ipfs/node_modules/hapi/lib/connection.js:329:16)
    at process.nextTick (/Users/imp/code/js-ipfs/node_modules/shot/lib/response.js:27:36)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
        1) returns 200 and the response stream with the ping result

@ghost ghost assigned JGAntunes May 8, 2018
@JGAntunes
Copy link
Member

Sorry @diasdavid, made a change to simplify the Joi validation object but turns out didn't work. Reverted it, should be fine now. This reminds me, any reason for why we are rewriting all the errors - https://github.com/ipfs/js-ipfs/blob/master/src/http/error-handler.js#L16? Just because this overwrites the Joi validation default response which is quite handy to be honest.

argv.ipfs.pingPullStream(peerId, { count }),
pullCatch(err => {
throw err
}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell pull-catch is for catching an error in the stream without ending the stream.

If you want to throw an error when it occurs then just remove this, drain will throw if you don't pass a second arg (done(err)). Or if you want to be explicit and/or do some logging, pass the second arg and then throw the error if it exists.

i.e.

pull(
  argv.ipfs.pingPullStream(peerId, { count }),
  drain(({ Time, Text }) => { /* ... */ }, (err) => {
    if (err) throw err
  })
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @alanshaw I was a bit confused with how drain handled errors, hence the pull-catch. Cool 👍 going to update it.

'use strict'

const pull = require('pull-stream/pull')
const drain = require('pull-stream/sinks/drain')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, you can just const pull = require('pull-stream') and then use pull() and pull.drain()

let peer
try {
peer = libp2pNode.peerBook.get(peerId)
return cb(null, peer)
Copy link
Member

@alanshaw alanshaw May 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's best not to call a callback in a try block because if the callback function throws, it'll be caught by the catch block below and you'll get phantom errors that are difficult to debug and even worse your callback will be called again in the catch block. Instead, return in the catch block and move the success callback call outside the try block.

function getPacket (msg) {
// Default msg
const basePacket = {Success: false, Time: 0, Text: ''}
return Object.assign({}, basePacket, msg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super minor, but you don't need to assign to an empty object here because you're creating a new basePacket for every call.


function runPing (libp2pNode, statusStream, count, peer, cb) {
libp2pNode.ping(peer, (err, p) => {
log('Got peer', peer)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move after the if (err)? Might be misleading otherwise...

then: Joi.any().forbidden(),
otherwise: Joi.number().greater(0)
}),
count: Joi.number().greater(0),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Joi.number().integer()?

ipfsdA.api.pingPullStream(ipfsdBId, { count }),
pullCatch(err => {
expect(err).to.not.exist()
}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this assertion be done in the drain callback?

pullCatch(err => {
expect(err).to.not.exist()
}),
drain(({ Success, Time, Text }) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be being converted to lower case in JS land?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would either require the HTTP API to be changed (and consequently be different from the Go implementation) or the js-ipfs-api module to lowercase the responses (the later looks like a nicer option tbh). I'm not sure how desirable this would be, taking interoperability with go-ipfs and such into account. @diasdavid any thoughts?

Copy link
Member

@alanshaw alanshaw May 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the current precedent is for js-ipfs core and js-ipfs-api to be lowerCamelCase but js-ipfs http to be compatible with Go i.e. UpperCamelCase.

It means that the js-ipfs http layer needs to translate from lowerCamelCase to UpperCamelCase (example) and js-ipfs-api needs to translate responses from UpperCamelCase to lowerCamelCase (example).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JGAntunes did you see this ^^?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep yep, sorry about it @alanshaw! Started looking at it yesterday evening, will finish it as soon I have some time 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JGAntunes if you're busy I'm happy to finish this off on your behalf? You want to push what you've done?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alanshaw sure thing, feel free to pick it up if you have some time. I hope I'm not blocking anyone or anything with this. I'm away from my laptop, but tbh I hadn't done much, besides looking at similar stuff like you pointed out, copying some pieces of code and doing an initial skeleton of a transform stream that processed the ping response (all of this in js-ipfs-api). I'm counting on having some time to deal with this later this evening, but please do pick it up if you have a chance, just let me know 👍

parallel([
ipfsdA.api.swarm.connect.bind(ipfsdA.api, bMultiaddr),
ipfsdB.api.swarm.connect.bind(ipfsdB.api, cMultiaddr)
], (err) => setTimeout(() => done(err), 500)) // FIXME timeout needed for connections to succeed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing this, we should do a setInterval that times out after ~30 seconds or something like that. Inside the interval, we should check if both peers are connected with the other peer, and if they are, cancel the interval + timeout and move on. If the they are not connected after 30 seconds, fail the test. This makes the test rely less on artificial pauses in the test execution.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll pick this up meanwhile, as soon as I have some time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alanshaw
Copy link
Member

I'm 👀 at this now

@alanshaw
Copy link
Member

alanshaw commented May 14, 2018

Ok, so in this PR in core we have:
* ping(peer, opts, callback<err, pullStream>)

In js-ipfs-api we have already:
* ping(peer, opts, callback<err, Array<{success, text, time}>)
* pingReadableStream(peer, opts): Readable
* pingPullStream(peer, opts): PullStream

I'm currently changing core.ping in this PR to work like the API and adding the missing core.pingReadableStream and core.pingPullStream.

@JGAntunes it would be grand if you could open a PR against interface-ipfs-core with tests for these and a spec doc.

@ghost ghost assigned alanshaw May 14, 2018
@JGAntunes
Copy link
Member

JGAntunes commented May 14, 2018

Alright! That makes sense, only now I've figured that the js-ipfs core components should match the same API provided by the js-ipfs-api 😅 sorry about it, would have added it if I knew.

Ok @alanshaw, I'll look into interface-ipfs-core in the evening and also submit the fix for the connection setTimeout @victorbjelkholm mentioned.

@alanshaw
Copy link
Member

Thanks @JGAntunes, this branch should be good to create tests against now - it has the proposed core API :D

Good luck! 🚀 🚀 🚀

@alanshaw
Copy link
Member

@JGAntunes did you get anywhere last night with this? If not I can spend some time today porting these over to interface-ipfs-core. It's the last thing to do on the 0.29 release checklist.

@JGAntunes
Copy link
Member

Hey @alanshaw, sorry, no. Please do if you have some time 👍 I'll see if I can fix the setTimeout test meanwhile

@daviddias
Copy link
Member Author

@JGAntunes mind rebasing master onto this branch to get CI green?

@JGAntunes
Copy link
Member

Happy to rebase @diasdavid but CI wont go green until ipfs-inactive/js-ipfs-http-client#762 is merged and the interface-ipfs-core is updated. I'll see if I can look into it in the next couple of days.

@alanshaw
Copy link
Member

@JGAntunes all good, I'm just finishing off the interface-ipfs-core tests and will merge ipfs-inactive/js-ipfs-http-client#762, rebase this and then merge this.

@JGAntunes
Copy link
Member

Thanks @alanshaw! 🙌

JGAntunes and others added 2 commits May 16, 2018 14:20
* feat: implement `ipfs ping` flags #928

* feat: first shot at ping implementaion

* fix: ETOOMANYSTREAMS 😢

* chore: cleanup on the ping component

* chore: ping component linting

* chore: bump js-ipfs-api and fix http ping validation

* chore: add test to ping cli command

* chore: add ping cli test

* chore: refactor ping component and some cleanup

* chore: add tests to the ping http API

* fix: no need to check for peerRouting method in ping

* chore: add tests for ping core functionality
@daviddias
Copy link
Member Author

@alanshaw I've updated deps but CI is still pretty angry. Can you check what's up?

@alanshaw
Copy link
Member

Yep on it

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants