bare-rpc 1.3.4 → 1.3.6
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.d.ts +2 -0
- package/index.js +82 -2
- package/lib/outgoing-request.js +2 -0
- package/package.json +1 -1
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -42,6 +42,19 @@ module.exports = exports = class RPC {
|
|
|
42
42
|
this._stream.on('error', this._onerror).on('data', this._ondata).on('drain', this._ondrain)
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
// Whether there are no requests or responses currently in flight. Useful for
|
|
46
|
+
// determining when it is safe to tear down the underlying stream.
|
|
47
|
+
get idle() {
|
|
48
|
+
return (
|
|
49
|
+
this._outgoingRequests.size === 0 &&
|
|
50
|
+
this._outgoingResponses.size === 0 &&
|
|
51
|
+
this._incomingRequests.size === 0 &&
|
|
52
|
+
this._incomingResponses.size === 0 &&
|
|
53
|
+
this._pendingRequests.size === 0 &&
|
|
54
|
+
this._pendingResponses.size === 0
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
45
58
|
event(command) {
|
|
46
59
|
return new OutgoingEvent(this, command)
|
|
47
60
|
}
|
|
@@ -51,6 +64,14 @@ module.exports = exports = class RPC {
|
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
_sendMessage(message, cb) {
|
|
67
|
+
// Once the underlying stream is being torn down there is nowhere left to
|
|
68
|
+
// write, so drop the message and settle the callback immediately. This
|
|
69
|
+
// keeps stream teardown from stalling on a drain that will never arrive.
|
|
70
|
+
if (this._stream.destroying) {
|
|
71
|
+
if (cb) cb(null)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
54
75
|
const header = c.encode(m.header, message)
|
|
55
76
|
|
|
56
77
|
let flushed = this._stream.write(header)
|
|
@@ -90,6 +111,8 @@ module.exports = exports = class RPC {
|
|
|
90
111
|
this._outgoingRequests.set(request.id, request)
|
|
91
112
|
|
|
92
113
|
request._requestStream = new OutgoingStream(this, request, t.REQUEST, opts)
|
|
114
|
+
|
|
115
|
+
request._requestStream.on('close', () => this._gcOutgoingRequest(request))
|
|
93
116
|
} else {
|
|
94
117
|
this._incomingRequests.set(request.id, request)
|
|
95
118
|
|
|
@@ -114,12 +137,19 @@ module.exports = exports = class RPC {
|
|
|
114
137
|
this._outgoingResponses.set(request.id, request)
|
|
115
138
|
|
|
116
139
|
request._responseStream = new OutgoingStream(this, request, t.RESPONSE, opts)
|
|
140
|
+
|
|
141
|
+
request._responseStream.on('close', () => this._outgoingResponses.delete(request.id))
|
|
117
142
|
} else {
|
|
118
143
|
this._incomingResponses.set(request.id, request)
|
|
119
144
|
|
|
120
145
|
request._responseStream = new IncomingStream(this, request, t.RESPONSE, opts)
|
|
121
146
|
|
|
122
|
-
request._responseStream.on('close', () =>
|
|
147
|
+
request._responseStream.on('close', () => {
|
|
148
|
+
this._incomingResponses.delete(request.id)
|
|
149
|
+
|
|
150
|
+
request._responded = true
|
|
151
|
+
this._gcOutgoingRequest(request)
|
|
152
|
+
})
|
|
123
153
|
}
|
|
124
154
|
}
|
|
125
155
|
|
|
@@ -133,10 +163,54 @@ module.exports = exports = class RPC {
|
|
|
133
163
|
})
|
|
134
164
|
}
|
|
135
165
|
|
|
166
|
+
_gcOutgoingRequest(request) {
|
|
167
|
+
// The entry must stay reachable for as long as an incoming message might
|
|
168
|
+
// still target it; until the response has settled and, if the request was
|
|
169
|
+
// streamed, until the outgoing request stream has closed. Either can be the
|
|
170
|
+
// last to arrive, so only remove the entry once both have completed.
|
|
171
|
+
if (!request._responded) return
|
|
172
|
+
if (request._requestStream !== null && !request._requestStream.destroyed) return
|
|
173
|
+
|
|
174
|
+
this._outgoingRequests.delete(request.id)
|
|
175
|
+
}
|
|
176
|
+
|
|
136
177
|
_onerror(err) {
|
|
137
178
|
this._ondrain(err)
|
|
138
179
|
|
|
139
|
-
//
|
|
180
|
+
// Reject any request awaiting a plain reply. Requests whose response is
|
|
181
|
+
// delivered over a stream are torn down through that stream below.
|
|
182
|
+
for (const request of this._outgoingRequests.values()) {
|
|
183
|
+
if (request.received && request._responseStream === null) request._reject(err)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Collect the streams first, deduplicating as a single request may appear
|
|
187
|
+
// in more than one map, then destroy them once the maps have been cleared.
|
|
188
|
+
const streams = new Set()
|
|
189
|
+
|
|
190
|
+
for (const request of this._outgoingRequests.values()) {
|
|
191
|
+
if (request._requestStream !== null) streams.add(request._requestStream)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
for (const request of this._incomingRequests.values()) {
|
|
195
|
+
if (request._requestStream !== null) streams.add(request._requestStream)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
for (const request of this._outgoingResponses.values()) {
|
|
199
|
+
if (request._responseStream !== null) streams.add(request._responseStream)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
for (const request of this._incomingResponses.values()) {
|
|
203
|
+
if (request._responseStream !== null) streams.add(request._responseStream)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
this._outgoingRequests.clear()
|
|
207
|
+
this._outgoingResponses.clear()
|
|
208
|
+
this._incomingRequests.clear()
|
|
209
|
+
this._incomingResponses.clear()
|
|
210
|
+
this._pendingRequests.clear()
|
|
211
|
+
this._pendingResponses.clear()
|
|
212
|
+
|
|
213
|
+
for (const stream of streams) stream.destroy(err)
|
|
140
214
|
}
|
|
141
215
|
|
|
142
216
|
_ondata(data) {
|
|
@@ -226,8 +300,14 @@ module.exports = exports = class RPC {
|
|
|
226
300
|
if (request === undefined) return
|
|
227
301
|
|
|
228
302
|
if (message.error) {
|
|
303
|
+
request._responded = true
|
|
304
|
+
this._gcOutgoingRequest(request)
|
|
305
|
+
|
|
229
306
|
request._reject(message.error)
|
|
230
307
|
} else if (message.stream === 0) {
|
|
308
|
+
request._responded = true
|
|
309
|
+
this._gcOutgoingRequest(request)
|
|
310
|
+
|
|
231
311
|
request._resolve(message.data)
|
|
232
312
|
}
|
|
233
313
|
}
|
package/lib/outgoing-request.js
CHANGED