Skip to content

Commit 7611b2e

Browse files
dirkmcvasco-santos
authored andcommitted
feat: emit event when a remote peer's subscriptions change (#61)
1 parent c9f8d39 commit 7611b2e

File tree

4 files changed

+60
-31
lines changed

4 files changed

+60
-31
lines changed

README.md

+18
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ fsub.start((err) => {
5151
})
5252
```
5353

54+
## Events
55+
56+
Floodsub emits two kinds of events:
57+
1. `<topic>` when a message is received for a particular topic
58+
```Javascript
59+
fsub.on('fruit', (data) => { ... })
60+
```
61+
- `data`: a Buffer containing the data that was published to the topic
62+
2. `floodsub:subscription-change` when the local peer receives an update to the subscriptions of a remote peer.
63+
```Javascript
64+
fsub.on('floodsub:subscription-change', (peerInfo, topics, changes) => { ... })
65+
```
66+
- `peerInfo`: a [PeerInfo](https://github.com/libp2p/js-peer-info) object
67+
- `topics`: the topics that the peer is now subscribed to
68+
- `changes`: an array of `{ topicCID: <topic>, subscribe: <boolean> }`
69+
eg `[ { topicCID: 'fruit', subscribe: true }, { topicCID: 'vegetables': false } ]`
70+
71+
5472
## API
5573

5674
See https://libp2p.github.io/js-libp2p-floodsub

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class FloodSub extends BaseProtocol {
8181
const peer = this.peers.get(idB58Str)
8282
if (peer) {
8383
peer.updateSubscriptions(subs)
84+
this.emit('floodsub:subscription-change', peer.info, peer.topics, subs)
8485
}
8586
}
8687
}

test/2-nodes.js

+29-23
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,18 @@ describe('basics between 2 nodes', () => {
7777

7878
it('Subscribe to a topic:Z in nodeA', (done) => {
7979
fsA.subscribe('Z')
80-
setTimeout(() => {
80+
fsB.once('floodsub:subscription-change', (changedPeerInfo, changedTopics, changedSubs) => {
8181
expectSet(fsA.subscriptions, ['Z'])
8282
expect(fsB.peers.size).to.equal(1)
8383
expectSet(first(fsB.peers).topics, ['Z'])
84+
expect(changedPeerInfo.id.toB58String()).to.equal(first(fsB.peers).info.id.toB58String())
85+
expectSet(changedTopics, ['Z'])
86+
expect(changedSubs).to.be.eql([{ topicCID: 'Z', subscribe: true }])
8487
done()
85-
}, 100)
88+
})
8689
})
8790

8891
it('Publish to a topic:Z in nodeA', (done) => {
89-
fsB.once('Z', shouldNotHappen)
90-
91-
function shouldNotHappen (msg) { expect.fail() }
92-
9392
fsA.once('Z', (msg) => {
9493
expect(msg.data.toString()).to.equal('hey')
9594
fsB.removeListener('Z', shouldNotHappen)
@@ -102,8 +101,6 @@ describe('basics between 2 nodes', () => {
102101
})
103102

104103
it('Publish to a topic:Z in nodeB', (done) => {
105-
fsB.once('Z', shouldNotHappen)
106-
107104
fsA.once('Z', (msg) => {
108105
fsA.once('Z', shouldNotHappen)
109106
expect(msg.data.toString()).to.equal('banana')
@@ -135,6 +132,7 @@ describe('basics between 2 nodes', () => {
135132

136133
if (++counter === 10) {
137134
fsA.removeListener('Z', receivedMsg)
135+
fsB.removeListener('Z', shouldNotHappen)
138136
done()
139137
}
140138
}
@@ -157,6 +155,7 @@ describe('basics between 2 nodes', () => {
157155

158156
if (++counter === 10) {
159157
fsA.removeListener('Z', receivedMsg)
158+
fsB.removeListener('Z', shouldNotHappen)
160159
done()
161160
}
162161
}
@@ -170,11 +169,14 @@ describe('basics between 2 nodes', () => {
170169
fsA.unsubscribe('Z')
171170
expect(fsA.subscriptions.size).to.equal(0)
172171

173-
setTimeout(() => {
172+
fsB.once('floodsub:subscription-change', (changedPeerInfo, changedTopics, changedSubs) => {
174173
expect(fsB.peers.size).to.equal(1)
175174
expectSet(first(fsB.peers).topics, [])
175+
expect(changedPeerInfo.id.toB58String()).to.equal(first(fsB.peers).info.id.toB58String())
176+
expectSet(changedTopics, [])
177+
expect(changedSubs).to.be.eql([{ topicCID: 'Z', subscribe: false }])
176178
done()
177-
}, 100)
179+
})
178180
})
179181

180182
it('Publish to a topic:Z in nodeA nodeB', (done) => {
@@ -242,22 +244,26 @@ describe('basics between 2 nodes', () => {
242244
})
243245

244246
it('existing subscriptions are sent upon peer connection', (done) => {
245-
nodeA.dial(nodeB.peerInfo, (err) => {
246-
expect(err).to.not.exist()
247-
setTimeout(() => {
248-
expect(fsA.peers.size).to.equal(1)
249-
expect(fsB.peers.size).to.equal(1)
247+
parallel([
248+
cb => fsA.once('floodsub:subscription-change', () => cb()),
249+
cb => fsB.once('floodsub:subscription-change', () => cb())
250+
], () => {
251+
expect(fsA.peers.size).to.equal(1)
252+
expect(fsB.peers.size).to.equal(1)
250253

251-
expectSet(fsA.subscriptions, ['Za'])
252-
expect(fsB.peers.size).to.equal(1)
253-
expectSet(first(fsB.peers).topics, ['Za'])
254+
expectSet(fsA.subscriptions, ['Za'])
255+
expect(fsB.peers.size).to.equal(1)
256+
expectSet(first(fsB.peers).topics, ['Za'])
254257

255-
expectSet(fsB.subscriptions, ['Zb'])
256-
expect(fsA.peers.size).to.equal(1)
257-
expectSet(first(fsA.peers).topics, ['Zb'])
258+
expectSet(fsB.subscriptions, ['Zb'])
259+
expect(fsA.peers.size).to.equal(1)
260+
expectSet(first(fsA.peers).topics, ['Zb'])
258261

259-
done()
260-
}, 1000)
262+
done()
263+
})
264+
265+
nodeA.dial(nodeB.peerInfo, (err) => {
266+
expect(err).to.not.exist()
261267
})
262268
})
263269

test/multiple-nodes.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -59,46 +59,50 @@ describe('multiple nodes (more than 2)', () => {
5959
], (err) => {
6060
expect(err).to.not.exist()
6161
// wait for the pubsub pipes to be established
62-
setTimeout(done, 200)
62+
setTimeout(done, 1000)
6363
})
6464
})
6565

6666
it('subscribe to the topic on node a', (done) => {
6767
a.ps.subscribe('Z')
6868
expectSet(a.ps.subscriptions, ['Z'])
6969

70-
setTimeout(() => {
70+
b.ps.once('floodsub:subscription-change', () => {
7171
expect(b.ps.peers.size).to.equal(2)
72-
const topics = Array.from(b.ps.peers.values())[1].topics
72+
const aPeerId = a.libp2p.peerInfo.id.toB58String()
73+
const topics = b.ps.peers.get(aPeerId).topics
7374
expectSet(topics, ['Z'])
7475

7576
expect(c.ps.peers.size).to.equal(1)
7677
expectSet(first(c.ps.peers).topics, [])
7778

7879
done()
79-
}, 200)
80+
})
8081
})
8182

8283
it('subscribe to the topic on node b', (done) => {
8384
b.ps.subscribe('Z')
8485
expectSet(b.ps.subscriptions, ['Z'])
8586

86-
setTimeout(() => {
87+
parallel([
88+
cb => a.ps.once('floodsub:subscription-change', () => cb()),
89+
cb => c.ps.once('floodsub:subscription-change', () => cb())
90+
], () => {
8791
expect(a.ps.peers.size).to.equal(1)
8892
expectSet(first(a.ps.peers).topics, ['Z'])
8993

9094
expect(c.ps.peers.size).to.equal(1)
9195
expectSet(first(c.ps.peers).topics, ['Z'])
9296

9397
done()
94-
}, 200)
98+
})
9599
})
96100

97101
it('subscribe to the topic on node c', (done) => {
98102
c.ps.subscribe('Z')
99103
expectSet(c.ps.subscriptions, ['Z'])
100104

101-
setTimeout(() => {
105+
b.ps.once('floodsub:subscription-change', () => {
102106
expect(a.ps.peers.size).to.equal(1)
103107
expectSet(first(a.ps.peers).topics, ['Z'])
104108

@@ -108,7 +112,7 @@ describe('multiple nodes (more than 2)', () => {
108112
})
109113

110114
done()
111-
}, 200)
115+
})
112116
})
113117

114118
it('publish on node a', (done) => {

0 commit comments

Comments
 (0)