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

Client is not subscribed to topic but API node is #3467

Closed
v-stickykeys opened this issue Dec 31, 2020 · 2 comments
Closed

Client is not subscribed to topic but API node is #3467

v-stickykeys opened this issue Dec 31, 2020 · 2 comments

Comments

@v-stickykeys
Copy link

v-stickykeys commented Dec 31, 2020

  • Version:

Http Client

"ipfs-http-client": "48.1.1",

Daemon

"ipfs": "0.52.2",
"ipfs-http-server": "0.1.3"
  • Platform:

Darwin MBP 19.6.0 Darwin Kernel Version 19.6.0: Mon Aug 31 22:12:52 PDT 2020; root:xnu-6153.141.2~1/RELEASE_X86_64 x86_64

  • Subsystem:

Pubsub

Severity:

Low

Description:

When you subscribe to a topic from a jsipfs API node, it is listed as a topic from the perspective of the client. I.e. pubsub.ls lists the topic as a subscription.

However, the topic is not registered on the client, and no pubsub messages are received by the client because it doesn't have a handler until a call to pubsub.subscribe is made.

As this is likely an edge case I don't think a code change is needed here (a warning would be nice though!) but some documentation could help.

Steps to reproduce the error:

  1. Run a jsipfs node and subscribe to a topic
$ node api.js
// api.js
import IPFS from 'ipfs'
import HttpApi from 'ipfs-http-server'

const topic = '/ceramic/testnet-clay'

async function run() {
  const ipfs = await IPFS.create({
    libp2p: {
      config: {
        pubsub: {
          enabled: true
        }
      }
    }
  })

  await new HttpApi(ipfs).start()
  console.log('IPFS API server listening on port 5011')

  try {
    await ipfs.pubsub.subscribe(topic)
    console.log('subbed to topic', topic)
  } catch (error) {
    console.log('sub failed', topic, error)
  }
}

run()
  1. Run an http client script connected to the API
$ node client.js
// client.js
const ipfsClient = require("ipfs-http-client")

const topic = process.env.TOPIC || '/ceramic/testnet-clay'
const ipfsApiUrl = process.env.IPFS_API_URL || 'http://localhost:5011'

const run = async () => {
  const ipfs = ipfsClient({ url: ipfsApiUrl })

  const receiveMsg = (msg) => { console.log('receiving', JSON.stringify(msg)) }
  const timeout = 500

  resub()

  function resub() {
    setInterval(async () => {
      let subbed = await subbedAccordingToLs()
      if (subbed === true) console.log('ls says we are subscribed')
      subbed = await subbedAccordingToSub()
      if (subbed === false) console.log('sub says we were not subscribed, but now we are')
    }, 5000)
  }

  async function subbedAccordingToLs() {
    let currentlySubbed
    await ipfs.pubsub.ls({ timeout })
      .then((subs) => {
        console.log('subs', subs)
        currentlySubbed = subs.includes(topic)
      })
      .catch((error) => {
        console.error(error.message)
        currentlySubbed = undefined
      })
    return currentlySubbed
  }

  async function subbedAccordingToSub() {
    let alreadySubbed
    await ipfs.pubsub.subscribe(topic, receiveMsg, { timeout })
      .then(() => {
        alreadySubbed = false
      })
      .catch((error) => {
        if (error.message.includes('Already subscribed')) {
          console.log(error.message)
          alreadySubbed = true
        } else {
          console.error(error.message)
          alreadySubbed = undefined
        }
      })
    return alreadySubbed
  }
}

run()
  1. Notice the output
$ node client.resub.js
subs [ '/ceramic/testnet-clay' ]
ls says we are subscribed
sub says we were not subscribed, but now we are
subs [ '/ceramic/testnet-clay' ]
ls says we are subscribed
Already subscribed to /ceramic/testnet-clay with this handler
@Gozala
Copy link
Contributor

Gozala commented Jan 7, 2021

@valmack I see how this can be confusing, however I do not think there is an issue here. Client is just a remote controller of the node so ls returns all the topics that node is subscribed to regardless if they were established from this client or not. That is also why ls reports the topic that client has not subscribed to (node itself did).

Also note that first subscribe succeeds because receiveMsg handler is not registered yet, but fails in subsequent calls because it has been. If you were to use different handlers (e.g. inline function) every subscribe would have succeeded.

That said I understand this makes ls inadequate for detecting if client is subscribed to the topic. Maybe an argument could be made to add an option option to only list local subscriptions, but even that could be misleading as some other part of the program could have subscribed with a different handler. It is also worth considering if this would be necessary with proposed API #3465 (comment)

@valmack does this explanation makes sense ? And do we need to do something here ?

@Gozala Gozala added status/ready Ready to be worked and removed need/triage Needs initial labeling and prioritization labels Jan 14, 2021
@whizzzkid whizzzkid assigned achingbrain and unassigned whizzzkid May 23, 2023
@SgtPooki
Copy link
Member

js-ipfs is being deprecated in favor of Helia. You can #4336 and read the migration guide.

Please feel to reopen with any comments by 2023-06-02. We will do a final pass on reopened issues afterward (see #4336).

I believe Gozala answered the concerns here, but moving forward, you should look to using kubo-rpc-client for your needs!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Status: Done
Development

No branches or pull requests

5 participants