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

Commit f11f2ce

Browse files
paralinachingbrain
andauthored
fix!: upgrade to interface-stream-muxer 2.0.0 (#186)
Adds the close() function to the StreamMuxer interface. Fixes #185 Co-authored-by: achingbrain <[email protected]>
1 parent 2578519 commit f11f2ce

File tree

2 files changed

+36
-25
lines changed

2 files changed

+36
-25
lines changed

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
],
3636
"exports": {
3737
".": {
38-
"types": "./src/index.d.ts",
38+
"types": "./dist/src/index.d.ts",
3939
"import": "./dist/src/index.js"
4040
}
4141
},
@@ -143,9 +143,9 @@
143143
"dependencies": {
144144
"@libp2p/components": "^2.0.0",
145145
"@libp2p/interface-connection": "^2.0.0",
146-
"@libp2p/interface-stream-muxer": "^1.0.1",
146+
"@libp2p/interface-stream-muxer": "^2.0.0",
147147
"@libp2p/logger": "^2.0.0",
148-
"@libp2p/tracked-map": "^1.0.5",
148+
"@libp2p/tracked-map": "^2.0.0",
149149
"abortable-iterator": "^4.0.2",
150150
"any-signal": "^3.0.0",
151151
"err-code": "^3.0.1",
@@ -157,7 +157,7 @@
157157
"varint": "^6.0.0"
158158
},
159159
"devDependencies": {
160-
"@libp2p/interface-stream-muxer-compliance-tests": "^2.0.0",
160+
"@libp2p/interface-stream-muxer-compliance-tests": "^3.0.1",
161161
"@types/varint": "^6.0.0",
162162
"aegir": "^37.2.0",
163163
"cborg": "^1.8.1",
@@ -168,6 +168,7 @@
168168
"it-foreach": "^0.1.1",
169169
"it-map": "^1.0.6",
170170
"p-defer": "^4.0.0",
171-
"random-int": "^3.0.0"
171+
"random-int": "^3.0.0",
172+
"typescript": "^4.7.4"
172173
}
173174
}

src/mplex.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import type { Sink } from 'it-stream-types'
1515
import type { StreamMuxer, StreamMuxerInit } from '@libp2p/interface-stream-muxer'
1616
import type { Stream } from '@libp2p/interface-connection'
1717
import type { MplexInit } from './index.js'
18+
import anySignal from 'any-signal'
1819

1920
const log = logger('libp2p:mplex')
2021

@@ -55,6 +56,7 @@ export class MplexStreamMuxer implements StreamMuxer {
5556
private readonly _streams: { initiators: Map<number, MplexStream>, receivers: Map<number, MplexStream> }
5657
private readonly _init: MplexStreamMuxerInit
5758
private readonly _source: { push: (val: Message) => void, end: (err?: Error) => void }
59+
private readonly closeController: AbortController
5860

5961
constructor (components: Components, init?: MplexStreamMuxerInit) {
6062
init = init ?? {}
@@ -83,12 +85,15 @@ export class MplexStreamMuxer implements StreamMuxer {
8385
const source = this._createSource()
8486
this._source = source
8587
this.source = source
86-
}
87-
88-
init (components: Components) {
8988

89+
/**
90+
* Close controller
91+
*/
92+
this.closeController = new AbortController()
9093
}
9194

95+
init (components: Components) {}
96+
9297
/**
9398
* Returns a Map of streams and their ids
9499
*/
@@ -109,12 +114,29 @@ export class MplexStreamMuxer implements StreamMuxer {
109114
* provided, the id of the stream will be used.
110115
*/
111116
newStream (name?: string): Stream {
117+
if (this.closeController.signal.aborted) {
118+
throw new Error('Muxer already closed')
119+
}
112120
const id = this._streamId++
113121
name = name == null ? id.toString() : name.toString()
114122
const registry = this._streams.initiators
115123
return this._newStream({ id, name, type: 'initiator', registry })
116124
}
117125

126+
/**
127+
* Close or abort all tracked streams and stop the muxer
128+
*/
129+
close (err?: Error | undefined): void {
130+
if (this.closeController.signal.aborted) return
131+
132+
if (err != null) {
133+
this.streams.forEach(s => s.abort(err))
134+
} else {
135+
this.streams.forEach(s => s.close())
136+
}
137+
this.closeController.abort()
138+
}
139+
118140
/**
119141
* Called whenever an inbound stream is created
120142
*/
@@ -177,9 +199,12 @@ export class MplexStreamMuxer implements StreamMuxer {
177199
*/
178200
_createSink () {
179201
const sink: Sink<Uint8Array> = async source => {
202+
// see: https://github.com/jacobheun/any-signal/pull/18
203+
const abortSignals = [this.closeController.signal]
180204
if (this._init.signal != null) {
181-
source = abortableSource(source, this._init.signal)
205+
abortSignals.push(this._init.signal)
182206
}
207+
source = abortableSource(source, anySignal(abortSignals))
183208

184209
try {
185210
await pipe(
@@ -209,22 +234,7 @@ export class MplexStreamMuxer implements StreamMuxer {
209234
*/
210235
_createSource () {
211236
const onEnd = (err?: Error) => {
212-
const { initiators, receivers } = this._streams
213-
// Abort all the things!
214-
for (const s of initiators.values()) {
215-
if (err != null) {
216-
s.abort(err)
217-
} else {
218-
s.close()
219-
}
220-
}
221-
for (const s of receivers.values()) {
222-
if (err != null) {
223-
s.abort(err)
224-
} else {
225-
s.close()
226-
}
227-
}
237+
this.close(err)
228238
}
229239
const source = pushableV<Message>({
230240
objectMode: true,

0 commit comments

Comments
 (0)