@@ -5,6 +5,8 @@ const TimeCache = require('time-cache')
5
5
const values = require ( 'lodash.values' )
6
6
const pull = require ( 'pull-stream' )
7
7
const lp = require ( 'pull-length-prefixed' )
8
+ const assert = require ( 'assert' )
9
+ const asyncEach = require ( 'async/each' )
8
10
9
11
const Peer = require ( './peer' )
10
12
const utils = require ( './utils' )
@@ -16,20 +18,20 @@ const multicodec = config.multicodec
16
18
const ensureArray = utils . ensureArray
17
19
18
20
/**
19
- * PubSubGossip, also known as pubsub-flood or just dumbsub,
20
- * this implementation of pubsub focused on delivering an API
21
- * for Publish/Subscribe, but with no CastTree Forming
21
+ * FloodSub (aka dumbsub is an implementation of pubsub focused on
22
+ * delivering an API for Publish/Subscribe, but with no CastTree Forming
22
23
* (it just floods the network).
23
24
*/
24
25
class FloodSub extends EventEmitter {
25
26
/**
26
27
* @param {Object } libp2p
27
- * @returns {PubSubGossip }
28
+ * @returns {FloodSub }
28
29
*/
29
30
constructor ( libp2p ) {
30
31
super ( )
31
32
32
33
this . libp2p = libp2p
34
+ this . started = false
33
35
34
36
/**
35
37
* Time based cache for sequence numbers.
@@ -51,18 +53,8 @@ class FloodSub extends EventEmitter {
51
53
*/
52
54
this . subscriptions = new Set ( )
53
55
54
- const onConnection = this . _onConnection . bind ( this )
55
- this . libp2p . handle ( multicodec , onConnection )
56
-
57
- // Speed up any new peer that comes in my way
58
- this . libp2p . swarm . on ( 'peer-mux-established' , ( p ) => {
59
- this . _dialPeer ( p )
60
- } )
61
-
62
- // Dial already connected peers
63
- values ( this . libp2p . peerBook . getAll ( ) ) . forEach ( ( p ) => {
64
- this . _dialPeer ( p )
65
- } )
56
+ this . _onConnection = this . _onConnection . bind ( this )
57
+ this . _dialPeer = this . _dialPeer . bind ( this )
66
58
}
67
59
68
60
_dialPeer ( peerInfo ) {
@@ -199,6 +191,62 @@ class FloodSub extends EventEmitter {
199
191
} )
200
192
}
201
193
194
+ /**
195
+ * Mounts the floodsub protocol onto the libp2p node and sends our
196
+ * subscriptions to every peer conneceted
197
+ *
198
+ * @param {Function } callback
199
+ * @returns {undefined }
200
+ *
201
+ */
202
+ start ( callback ) {
203
+ if ( this . started ) {
204
+ return setImmediate ( ( ) => callback ( new Error ( 'already started' ) ) )
205
+ }
206
+
207
+ this . libp2p . handle ( multicodec , this . _onConnection )
208
+
209
+ // Speed up any new peer that comes in my way
210
+ this . libp2p . swarm . on ( 'peer-mux-established' , this . _dialPeer )
211
+
212
+ // Dial already connected peers
213
+ const peerInfos = values ( this . libp2p . peerBook . getAll ( ) )
214
+
215
+ peerInfos . forEach ( ( peerInfo ) => {
216
+ this . _dialPeer ( peerInfo )
217
+ } )
218
+
219
+ setImmediate ( ( ) => {
220
+ this . started = true
221
+ callback ( )
222
+ } )
223
+ }
224
+
225
+ /**
226
+ * Unmounts the floodsub protocol and shuts down every connection
227
+ *
228
+ * @param {Function } callback
229
+ * @returns {undefined }
230
+ *
231
+ */
232
+ stop ( callback ) {
233
+ if ( ! this . started ) {
234
+ return setImmediate ( ( ) => callback ( new Error ( 'not started yet' ) ) )
235
+ }
236
+
237
+ this . libp2p . unhandle ( multicodec )
238
+ this . libp2p . swarm . removeListener ( 'peer-mux-established' , this . _dialPeer )
239
+
240
+ asyncEach ( this . peers . values ( ) , ( peer , cb ) => peer . close ( cb ) , ( err ) => {
241
+ if ( err ) {
242
+ return callback ( err )
243
+ }
244
+ this . peers = new Map ( )
245
+ this . started = false
246
+ callback ( )
247
+ } )
248
+ }
249
+
202
250
/**
203
251
* Publish messages to the given topics.
204
252
*
@@ -208,6 +256,8 @@ class FloodSub extends EventEmitter {
208
256
*
209
257
*/
210
258
publish ( topics , messages ) {
259
+ assert ( this . started , 'FloodSub is not started' )
260
+
211
261
log ( 'publish' , topics , messages )
212
262
213
263
topics = ensureArray ( topics )
@@ -243,6 +293,8 @@ class FloodSub extends EventEmitter {
243
293
* @returns {undefined }
244
294
*/
245
295
subscribe ( topics ) {
296
+ assert ( this . started , 'FloodSub is not started' )
297
+
246
298
topics = ensureArray ( topics )
247
299
248
300
topics . forEach ( ( topic ) => {
@@ -261,6 +313,7 @@ class FloodSub extends EventEmitter {
261
313
* @returns {undefined }
262
314
*/
263
315
unsubscribe ( topics ) {
316
+ assert ( this . started , 'FloodSub is not started' )
264
317
topics = ensureArray ( topics )
265
318
266
319
topics . forEach ( ( topic ) => {
0 commit comments