Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

Why poll? #70

Open
richardschneider opened this issue Feb 2, 2018 · 17 comments
Open

Why poll? #70

richardschneider opened this issue Feb 2, 2018 · 17 comments
Labels
status/ready Ready to be worked

Comments

@richardschneider
Copy link
Contributor

Every 10 seconds a multicast query is sent. I assume it is done to find new IPFS peers.

Every time a new peer starts, it will send a query and ALSO respond to it with it's info.

Since this is multicast, all other nodes will see its response and add the peer to it's tables.

So polling every 10s is not needed.

@richardschneider
Copy link
Contributor Author

@whyrusleeping @diasdavid @Stebalien please comment

@whyrusleeping
Copy link

@richardschneider are you sure? If thats the case, then we could remove the polling. I would like to see it working in practice without polling before I would be okay disabling it though

@richardschneider
Copy link
Contributor Author

@whyrusleeping added a test to PR #71

  it('find all peers', function (done) {
    const options = {
      port: 50001 // port must be the same
    }
    const mdnsA = new MulticastDNS(pA, options)
    const mdnsB = new MulticastDNS(pB, options)
    const mdnsC = new MulticastDNS(pC, options)
    const peersA = {}
    const peersB = {}
    const peersC = {}

    // After all the peers have started, each peer should see two other peers.
    function check (receiver, peerInfo) {
      receiver[peerInfo.id.toB58String()] = true
      if (Object.keys(peersA).length === 2 && Object.keys(peersB).length === 2 && Object.keys(peersC).length === 2) {
        parallel([
          (cb) => mdnsA.stop(cb),
          (cb) => mdnsB.stop(cb),
          (cb) => mdnsC.stop(cb)
        ], done)
      }
    }
    mdnsA.on('peer', (peerInfo) => check(peersA, peerInfo))
    mdnsB.on('peer', (peerInfo) => check(peersB, peerInfo))
    mdnsC.on('peer', (peerInfo) => check(peersC, peerInfo))
    series([
      (cb) => mdnsA.start(cb),
      (cb) => setTimeout(cb, 500),
      (cb) => mdnsB.start(cb),
      (cb) => setTimeout(cb, 500),
      (cb) => mdnsC.start(cb)
    ], () => {})
  })

@richardschneider
Copy link
Contributor Author

ipfs/js-ipfs#1123

@daviddias daviddias added the status/ready Ready to be worked label Feb 5, 2018
@Stebalien
Copy link
Member

That sounds correct however, it doesn't handle the case of joining/leaving networks. Ideally, libp2p would expose an API to monitor for new network addresses (I want this so badly) but implementing this properly is a pain (although we should have something that just does this on a timer anyways...).

For now, maybe poll once every 10 minutes, every half hour? That should at least cover the case of "close laptop, move elsewhere, open laptop, discover peers".

@richardschneider
Copy link
Contributor Author

I really don't like network polling because it doesn't scale well; see comment.

How about, detecting an "open laptop" and then do a "discover peers". Something like sleeptime can be used to detect "open laptop".

@mkg20001
Copy link
Member

mkg20001 commented Feb 7, 2018

Btw, sleeptime has a typo that prevents custom intervals from working (timrach/sleeptime#1) and breaks if the application does too much work on it's main thread (edit: with break i mean that it does trigger even if the laptop wasn't asleep) (edit2: could be fixed by using child_process.fork and notifying the main process over ipc)

@richardschneider
Copy link
Contributor Author

@mkg20001 Thank's for the heads-up.

I assume that 'breaking' (false positives) is dependent on the interval. The lower the interval the more likely a false-positive is triggered. I would expect our interval to be 1 or 2 minutes. Hopefully, our app would not spend that amount of time on the 'main thread'.

@richardschneider
Copy link
Contributor Author

Also, sleeptime needs a stop method, so that mdns can gracefully shutdown.

@Stebalien
Copy link
Member

@richardschneider that's a fair point but, in go at least, have a server profile that disables mdns for this reason. Also, I'd hope that most datacenters turn of multicast (or at least multicaset between multiple customers).

In go-libp2p, we have a InterfaceListenAddresses method that'll return all fully-specified we're listening on, resolving, e.g., 0.0.0.0 to our local machine's actual IP addresses. Is there an equivalent in javascript? That's what I'd use to detect interface changes.

Note: this still won't handle cases of networks joining each other but... that's not exactly a common case that I care about.

@richardschneider
Copy link
Contributor Author

I think I read in the MDNS RFC that mutlicasting is for the local network and not joined networks, but I could be wrong.

@Stebalien
Copy link
Member

I was thinking about network partitions. If my network gets partitioned, I join, and then it gets unpartitioned, I will never advertise myself to the other partition. However, on local networks this is really not that much of an issue.

@mkg20001
Copy link
Member

mkg20001 commented Feb 8, 2018

Also, sleeptime needs a stop method, so that mdns can gracefully shutdown.

@richardschneider I have created a rewritten version of sleeptime (https://github.com/mkg20001/sleeptime2) that fixes that issue and the other I mentioned above

@richardschneider
Copy link
Contributor Author

@mkg20001 sleeptime2 creates a child process to do the monitoring. It's a bit resource intensive for such a simple function. Also, has node IPC been tested on windows?

@mkg20001
Copy link
Member

mkg20001 commented Feb 8, 2018

@richardschneider The IPC is one of nodes core apis so it should work on windows.
Also it's better to fork instead of running it in the main thread as the application could sometimes do so much work that it would trigger a false positive

@richardschneider
Copy link
Contributor Author

A fork in node-land creates an entire new process, as opposed to win/*nix which just creates a light weight thread.

@richardschneider
Copy link
Contributor Author

To paraphrase Jörgen Sigvardsson

It is considered bad etiquette to spam with MDNS queries. Only query at startup, and listen for publications by other services. Don't make the same query every ten seconds!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status/ready Ready to be worked
Projects
None yet
Development

No branches or pull requests

5 participants