bare-rpc 1.3.5 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +60 -2
- package/lib/errors.d.ts +2 -0
- package/lib/errors.js +4 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -2,6 +2,7 @@ const safetyCatch = require('safety-catch')
|
|
|
2
2
|
const b4a = require('b4a')
|
|
3
3
|
const c = require('compact-encoding')
|
|
4
4
|
const m = require('./lib/messages')
|
|
5
|
+
const errors = require('./lib/errors')
|
|
5
6
|
const { type: t, stream: s } = require('./lib/constants')
|
|
6
7
|
const IncomingEvent = require('./lib/incoming-event')
|
|
7
8
|
const IncomingRequest = require('./lib/incoming-request')
|
|
@@ -36,10 +37,15 @@ module.exports = exports = class RPC {
|
|
|
36
37
|
|
|
37
38
|
this._onrequest = onrequest
|
|
38
39
|
this._onerror = this._onerror.bind(this)
|
|
40
|
+
this._onclose = this._onclose.bind(this)
|
|
39
41
|
this._ondata = this._ondata.bind(this)
|
|
40
42
|
this._ondrain = this._ondrain.bind(this)
|
|
41
43
|
|
|
42
|
-
this._stream
|
|
44
|
+
this._stream
|
|
45
|
+
.on('error', this._onerror)
|
|
46
|
+
.on('close', this._onclose)
|
|
47
|
+
.on('data', this._ondata)
|
|
48
|
+
.on('drain', this._ondrain)
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
// Whether there are no requests or responses currently in flight. Useful for
|
|
@@ -64,6 +70,14 @@ module.exports = exports = class RPC {
|
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
_sendMessage(message, cb) {
|
|
73
|
+
// Once the underlying stream is being torn down there is nowhere left to
|
|
74
|
+
// write, so drop the message and settle the callback immediately. This
|
|
75
|
+
// keeps stream teardown from stalling on a drain that will never arrive.
|
|
76
|
+
if (this._stream.destroying) {
|
|
77
|
+
if (cb) cb(null)
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
67
81
|
const header = c.encode(m.header, message)
|
|
68
82
|
|
|
69
83
|
let flushed = this._stream.write(header)
|
|
@@ -167,9 +181,53 @@ module.exports = exports = class RPC {
|
|
|
167
181
|
}
|
|
168
182
|
|
|
169
183
|
_onerror(err) {
|
|
184
|
+
this._teardown(err)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
_onclose() {
|
|
188
|
+
// A clean close of the underlying stream leaves in-flight requests and
|
|
189
|
+
// responses with nowhere to complete, so tear them down as if the channel
|
|
190
|
+
// had errored.
|
|
191
|
+
this._teardown(errors.CHANNEL_CLOSED('Channel closed'))
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
_teardown(err) {
|
|
170
195
|
this._ondrain(err)
|
|
171
196
|
|
|
172
|
-
//
|
|
197
|
+
// Reject any request awaiting a plain reply. Requests whose response is
|
|
198
|
+
// delivered over a stream are torn down through that stream below.
|
|
199
|
+
for (const request of this._outgoingRequests.values()) {
|
|
200
|
+
if (request.received && request._responseStream === null) request._reject(err)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Collect the streams first, deduplicating as a single request may appear
|
|
204
|
+
// in more than one map, then destroy them once the maps have been cleared.
|
|
205
|
+
const streams = new Set()
|
|
206
|
+
|
|
207
|
+
for (const request of this._outgoingRequests.values()) {
|
|
208
|
+
if (request._requestStream !== null) streams.add(request._requestStream)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (const request of this._incomingRequests.values()) {
|
|
212
|
+
if (request._requestStream !== null) streams.add(request._requestStream)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
for (const request of this._outgoingResponses.values()) {
|
|
216
|
+
if (request._responseStream !== null) streams.add(request._responseStream)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
for (const request of this._incomingResponses.values()) {
|
|
220
|
+
if (request._responseStream !== null) streams.add(request._responseStream)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
this._outgoingRequests.clear()
|
|
224
|
+
this._outgoingResponses.clear()
|
|
225
|
+
this._incomingRequests.clear()
|
|
226
|
+
this._incomingResponses.clear()
|
|
227
|
+
this._pendingRequests.clear()
|
|
228
|
+
this._pendingResponses.clear()
|
|
229
|
+
|
|
230
|
+
for (const stream of streams) stream.destroy(err)
|
|
173
231
|
}
|
|
174
232
|
|
|
175
233
|
_ondata(data) {
|
package/lib/errors.d.ts
CHANGED
package/lib/errors.js
CHANGED
|
@@ -23,4 +23,8 @@ module.exports = class RPCError extends Error {
|
|
|
23
23
|
static ALREADY_RECEIVED(msg) {
|
|
24
24
|
return new RPCError(msg, 'ALREADY_RECEIVED', RPCError.ALREADY_RECEIVED)
|
|
25
25
|
}
|
|
26
|
+
|
|
27
|
+
static CHANNEL_CLOSED(msg) {
|
|
28
|
+
return new RPCError(msg, 'CHANNEL_CLOSED', RPCError.CHANNEL_CLOSED)
|
|
29
|
+
}
|
|
26
30
|
}
|