tchannel 3.6.14 → 3.6.24
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/as/http.js +2 -2
- package/benchmarks/Makefile +5 -1
- package/benchmarks/index.js +1 -0
- package/benchmarks/multi_bench.js +15 -1
- package/channel.js +18 -5
- package/hyperbahn-client.js +3 -1
- package/lazy_relay.js +167 -24
- package/lib/object_pool.js +209 -0
- package/package.json +4 -4
- package/peer.js +143 -6
- package/peer_heap.js +52 -36
- package/relay_handler.js +4 -1
- package/service-name-handler.js +4 -1
- package/stat-tags.js +24 -1
- package/sub_peers.js +79 -9
- package/test/index.js +2 -0
- package/test/lazy_conn_handler.js +6 -2
- package/test/lazy_handler.js +6 -2
- package/test/lib/alloc-cluster.js +27 -1
- package/test/lib/batch-client.js +17 -2
- package/test/object_pool.js +119 -0
- package/test/peer-to-peer-load-balance.js +459 -0
- package/test/relay_lazy.js +2 -1
- package/test/v2/call.js +1 -0
- package/test/v2/lazy_frame.js +17 -12
- package/v2/args.js +28 -29
- package/v2/call.js +108 -68
- package/v2/checksum.js +2 -2
- package/v2/cont.js +19 -18
- package/v2/error_response.js +6 -8
- package/v2/frame.js +16 -14
- package/v2/handler.js +4 -1
- package/v2/header.js +30 -29
- package/v2/init.js +10 -12
- package/v2/tracing.js +21 -20
package/as/http.js
CHANGED
|
@@ -261,7 +261,7 @@ TChannelHTTP.prototype.sendRequest = function send(treq, hreq, start, options, c
|
|
|
261
261
|
self.logger.error('Buffer read for arg2 failed', {
|
|
262
262
|
error: arg2res.err
|
|
263
263
|
});
|
|
264
|
-
var fromBufferErr = errors.
|
|
264
|
+
var fromBufferErr = errors.HTTPReqArg2fromBufferError(arg2res.err, {
|
|
265
265
|
arg2: res1
|
|
266
266
|
});
|
|
267
267
|
callback(fromBufferErr, null, null, null);
|
|
@@ -557,7 +557,7 @@ AsHTTPHandler.prototype.handleRequest = function handleRequest(req, buildRespons
|
|
|
557
557
|
self.logger.error('Buffer read for arg2 failed', {
|
|
558
558
|
error: arg2res.err
|
|
559
559
|
});
|
|
560
|
-
var fromBufferErr = errors.
|
|
560
|
+
var fromBufferErr = errors.HTTPResArg2fromBufferError(arg2res.err, {
|
|
561
561
|
arg2: arg2
|
|
562
562
|
});
|
|
563
563
|
sendError(fromBufferErr);
|
package/benchmarks/Makefile
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
torch-client-bench:
|
|
2
2
|
node index.js --relay --torch client --torchFile ./flame.raw --torchTime 10 \
|
|
3
|
-
-- --relay --skipPing -s 4096,16384 -p 1000
|
|
3
|
+
-- --relay --skipPing -s 4096,16384 -p 1000 -m 3
|
|
4
|
+
|
|
5
|
+
torch-client-only-bench:
|
|
6
|
+
node index.js --torch client --torchFile ./flame.raw --torchTime 10 \
|
|
7
|
+
-- --skipPing -s 4096,16384 -p 1000 -m 3
|
|
4
8
|
|
|
5
9
|
torch-server-bench:
|
|
6
10
|
node index.js --relay --torch server --torchFile ./flame.raw --torchTime 10 \
|
package/benchmarks/index.js
CHANGED
|
@@ -265,6 +265,7 @@ function startClient(clientPort) {
|
|
|
265
265
|
'--benchPort', String(self.ports.serverPort),
|
|
266
266
|
'--relayServerPort', String(self.ports.relayServerPort),
|
|
267
267
|
'--clientPort', String(clientPort),
|
|
268
|
+
'--instances', String(self.instanceCount),
|
|
268
269
|
'--instanceNumber', String(self.benchCounter)
|
|
269
270
|
]);
|
|
270
271
|
var benchProc = self.run(bench, args);
|
|
@@ -63,13 +63,17 @@ argv.pipeline = parseIntList(argv.pipeline);
|
|
|
63
63
|
argv.sizes = parseIntList(argv.sizes);
|
|
64
64
|
|
|
65
65
|
var DESTINATION_SERVER;
|
|
66
|
+
var DESTINATION_PORT;
|
|
66
67
|
var TRACE_SERVER;
|
|
67
68
|
var CLIENT_PORT = argv.clientPort;
|
|
69
|
+
var INSTANCES = 0;
|
|
68
70
|
|
|
69
71
|
if (argv.relay) {
|
|
70
72
|
DESTINATION_SERVER = '127.0.0.1:' + argv.relayServerPort;
|
|
71
73
|
} else {
|
|
72
74
|
DESTINATION_SERVER = '127.0.0.1:' + argv.benchPort;
|
|
75
|
+
DESTINATION_PORT = argv.benchPort;
|
|
76
|
+
INSTANCES = parseInt(argv.instances, 10);
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
if (argv.trace) {
|
|
@@ -171,9 +175,19 @@ Test.prototype.newClient = function newClient(id, callback) {
|
|
|
171
175
|
};
|
|
172
176
|
}
|
|
173
177
|
|
|
178
|
+
var peers = [DESTINATION_SERVER];
|
|
179
|
+
if (INSTANCES > 0) {
|
|
180
|
+
peers = [];
|
|
181
|
+
var basePort = DESTINATION_PORT;
|
|
182
|
+
for (var i = 0; i < INSTANCES; i++) {
|
|
183
|
+
peers.push('127.0.0.1:' + (basePort + i));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
174
187
|
var client = clientChan.makeSubChannel({
|
|
175
188
|
serviceName: 'benchmark',
|
|
176
|
-
peers:
|
|
189
|
+
peers: peers,
|
|
190
|
+
minConnections: INSTANCES > 0 ? 10 : 1
|
|
177
191
|
});
|
|
178
192
|
client.createTime = Date.now();
|
|
179
193
|
clientChan.listen(port, '127.0.0.1', function listened(err) {
|
package/channel.js
CHANGED
|
@@ -55,6 +55,7 @@ var TChannelRequest = require('./request');
|
|
|
55
55
|
var TChannelServiceNameHandler = require('./service-name-handler');
|
|
56
56
|
var errors = require('./errors');
|
|
57
57
|
var EventEmitter = require('./lib/event_emitter.js');
|
|
58
|
+
var ObjectPool = require('./lib/object_pool');
|
|
58
59
|
|
|
59
60
|
var TChannelAsThrift = require('./as/thrift');
|
|
60
61
|
var TChannelAsJSON = require('./as/json');
|
|
@@ -121,7 +122,8 @@ function TChannel(options) {
|
|
|
121
122
|
this.emitConnectionMetrics =
|
|
122
123
|
typeof this.options.emitConnectionMetrics === 'boolean' ?
|
|
123
124
|
this.options.emitConnectionMetrics : false;
|
|
124
|
-
this.choosePeerWithHeap = this.options.choosePeerWithHeap
|
|
125
|
+
this.choosePeerWithHeap = typeof this.options.choosePeerWithHeap === 'boolean' ?
|
|
126
|
+
this.options.choosePeerWithHeap : true;
|
|
125
127
|
|
|
126
128
|
this.setObservePeerScoreEvents(this.options.observePeerScoreEvents);
|
|
127
129
|
|
|
@@ -253,6 +255,15 @@ function TChannel(options) {
|
|
|
253
255
|
this.batchStats = this.topChannel.batchStats;
|
|
254
256
|
}
|
|
255
257
|
|
|
258
|
+
if (this.batchStats) {
|
|
259
|
+
ObjectPool.bootstrap({
|
|
260
|
+
channel: this,
|
|
261
|
+
reportInterval: 5000,
|
|
262
|
+
timers: this.timers,
|
|
263
|
+
debug: this.options.objectPoolDebug ? true : false
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
256
267
|
this.maximumRelayTTL = MAXIMUM_TTL_ALLOWED;
|
|
257
268
|
|
|
258
269
|
function doSanitySweep() {
|
|
@@ -521,9 +532,6 @@ TChannel.prototype.onServerSocketConnection = function onServerSocketConnection(
|
|
|
521
532
|
TChannel.prototype.onServerSocketListening = function onServerSocketListening() {
|
|
522
533
|
var self = this;
|
|
523
534
|
|
|
524
|
-
var address = self.serverSocket.address();
|
|
525
|
-
var hostPort = self.host + ':' + address.port;
|
|
526
|
-
|
|
527
535
|
if (self.destroyed) {
|
|
528
536
|
self.logger.error('got serverSocket listen whilst destroyed', self.extendLogInfo({
|
|
529
537
|
requestedPort: self.requestedPort
|
|
@@ -531,7 +539,8 @@ TChannel.prototype.onServerSocketListening = function onServerSocketListening()
|
|
|
531
539
|
return;
|
|
532
540
|
}
|
|
533
541
|
|
|
534
|
-
|
|
542
|
+
var address = self.serverSocket.address();
|
|
543
|
+
self.hostPort = self.host + ':' + address.port;
|
|
535
544
|
self.listening = true;
|
|
536
545
|
|
|
537
546
|
if (self.subChannels) {
|
|
@@ -911,6 +920,10 @@ TChannel.prototype.close = function close(callback) {
|
|
|
911
920
|
|
|
912
921
|
var counter = 1;
|
|
913
922
|
|
|
923
|
+
if (self.batchStats) {
|
|
924
|
+
ObjectPool.unref();
|
|
925
|
+
}
|
|
926
|
+
|
|
914
927
|
if (self.sanityTimer) {
|
|
915
928
|
self.timers.clearTimeout(self.sanityTimer);
|
|
916
929
|
self.sanityTimer = null;
|
package/hyperbahn-client.js
CHANGED
package/lazy_relay.js
CHANGED
|
@@ -20,9 +20,16 @@
|
|
|
20
20
|
|
|
21
21
|
'use strict';
|
|
22
22
|
|
|
23
|
+
var process = require('process');
|
|
23
24
|
var errors = require('./errors');
|
|
24
25
|
var v2 = require('./v2');
|
|
25
26
|
var stat = require('./stat-tags.js');
|
|
27
|
+
var ObjectPool = require('./lib/object_pool');
|
|
28
|
+
var ReadResult = require('bufrw').ReadResult;
|
|
29
|
+
var WriteResult = require('bufrw').WriteResult;
|
|
30
|
+
|
|
31
|
+
var readRes = new ReadResult();
|
|
32
|
+
var writeRes = new WriteResult();
|
|
26
33
|
|
|
27
34
|
module.exports = {
|
|
28
35
|
LazyRelayInReq: LazyRelayInReq,
|
|
@@ -35,30 +42,30 @@ module.exports = {
|
|
|
35
42
|
|
|
36
43
|
/*eslint max-statements: [2, 40]*/
|
|
37
44
|
function LazyRelayInReq(conn, reqFrame) {
|
|
38
|
-
this.channel =
|
|
39
|
-
this.conn =
|
|
40
|
-
this.start =
|
|
41
|
-
this.remoteAddr =
|
|
42
|
-
this.logger =
|
|
45
|
+
this.channel = null;
|
|
46
|
+
this.conn = null;
|
|
47
|
+
this.start = null;
|
|
48
|
+
this.remoteAddr = null;
|
|
49
|
+
this.logger = null;
|
|
43
50
|
this.peer = null;
|
|
44
51
|
this.outreq = null;
|
|
45
|
-
this.reqFrame =
|
|
46
|
-
this.id =
|
|
47
|
-
this.serviceName =
|
|
48
|
-
this.callerName =
|
|
49
|
-
this.timeout =
|
|
50
|
-
this.alive =
|
|
52
|
+
this.reqFrame = null;
|
|
53
|
+
this.id = null;
|
|
54
|
+
this.serviceName = null;
|
|
55
|
+
this.callerName = null;
|
|
56
|
+
this.timeout = null;
|
|
57
|
+
this.alive = null;
|
|
51
58
|
this.operations = null;
|
|
52
59
|
this.timeHeapHandle = null;
|
|
53
|
-
this.endpoint =
|
|
60
|
+
this.endpoint = null;
|
|
54
61
|
this.error = null;
|
|
55
62
|
this.tracing = null;
|
|
56
63
|
this.reqContFrames = [];
|
|
57
|
-
this.hasRead =
|
|
64
|
+
this.hasRead = null;
|
|
65
|
+
this.waitForIdentSlot = null;
|
|
58
66
|
|
|
59
67
|
this.boundExtendLogInfo = extendLogInfo;
|
|
60
68
|
this.boundOnIdentified = onIdentified;
|
|
61
|
-
this.circuit = reqFrame.circuit;
|
|
62
69
|
|
|
63
70
|
var self = this;
|
|
64
71
|
|
|
@@ -67,6 +74,10 @@ function LazyRelayInReq(conn, reqFrame) {
|
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
function onIdentified(err) {
|
|
77
|
+
// The ident descriptor will be cleared out of the peer when the ident
|
|
78
|
+
// comes back, so this slot id will be invalid once ident happens.
|
|
79
|
+
self.waitForIdentSlot = -1;
|
|
80
|
+
|
|
70
81
|
if (err) {
|
|
71
82
|
self.onError(err);
|
|
72
83
|
} else {
|
|
@@ -75,6 +86,66 @@ function LazyRelayInReq(conn, reqFrame) {
|
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
|
|
89
|
+
LazyRelayInReq.prototype.reset = function reset(conn, reqFrame) {
|
|
90
|
+
this.channel = conn.channel;
|
|
91
|
+
this.conn = conn;
|
|
92
|
+
this.start = conn.timers.now();
|
|
93
|
+
this.remoteAddr = conn.remoteName;
|
|
94
|
+
this.logger = conn.logger;
|
|
95
|
+
this.peer = null;
|
|
96
|
+
this.outreq = null;
|
|
97
|
+
this.reqFrame = reqFrame;
|
|
98
|
+
this.id = this.reqFrame.id;
|
|
99
|
+
this.serviceName = '';
|
|
100
|
+
this.callerName = '';
|
|
101
|
+
this.timeout = 0;
|
|
102
|
+
this.alive = true;
|
|
103
|
+
this.operations = null;
|
|
104
|
+
this.timeHeapHandle = null;
|
|
105
|
+
this.endpoint = '';
|
|
106
|
+
this.error = null;
|
|
107
|
+
this.tracing = null;
|
|
108
|
+
this.reqContFrames.length = 0;
|
|
109
|
+
this.hasRead = false;
|
|
110
|
+
this.circuit = reqFrame.circuit;
|
|
111
|
+
this.waitForIdentSlot = null;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
LazyRelayInReq.prototype.clear = function clear() {
|
|
115
|
+
if (this.outreq && !this.outreq._objectPoolIsFreed) {
|
|
116
|
+
this.outreq.free();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (this.peer && this.waitForIdentSlot !== null) {
|
|
120
|
+
this.peer.stopWaitingForIdentified(this.waitForIdentSlot);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.channel = null;
|
|
124
|
+
this.conn = null;
|
|
125
|
+
this.start = null;
|
|
126
|
+
this.remoteAddr = null;
|
|
127
|
+
this.logger = null;
|
|
128
|
+
this.peer = null;
|
|
129
|
+
this.outreq = null;
|
|
130
|
+
this.reqFrame = null;
|
|
131
|
+
this.id = null;
|
|
132
|
+
this.serviceName = null;
|
|
133
|
+
this.callerName = null;
|
|
134
|
+
this.timeout = null;
|
|
135
|
+
this.alive = null;
|
|
136
|
+
this.operations = null;
|
|
137
|
+
this.timeHeapHandle = null;
|
|
138
|
+
this.endpoint = null;
|
|
139
|
+
this.error = null;
|
|
140
|
+
this.tracing = null;
|
|
141
|
+
this.reqContFrames.length = 0;
|
|
142
|
+
this.hasRead = null;
|
|
143
|
+
this.circuit = null;
|
|
144
|
+
this.waitForIdentSlot = null;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
ObjectPool.setup({Type: LazyRelayInReq, maxSize: 200});
|
|
148
|
+
|
|
78
149
|
LazyRelayInReq.prototype.type = 'tchannel.lazy.incoming-request';
|
|
79
150
|
|
|
80
151
|
LazyRelayInReq.prototype.initRead =
|
|
@@ -128,7 +199,7 @@ function initRead() {
|
|
|
128
199
|
self.endpoint = endpoint;
|
|
129
200
|
|
|
130
201
|
var tracing = self.reqFrame.bodyRW.lazy
|
|
131
|
-
.
|
|
202
|
+
.poolReadTracingValue(readRes, self.reqFrame);
|
|
132
203
|
self.tracing = tracing || v2.Tracing.emptyTracing;
|
|
133
204
|
|
|
134
205
|
self.channel.emitFastStat(
|
|
@@ -214,7 +285,7 @@ function createOutRequest() {
|
|
|
214
285
|
if (conn && conn.remoteName && !conn.closing) {
|
|
215
286
|
self.forwardTo(conn);
|
|
216
287
|
} else {
|
|
217
|
-
self.peer.waitForIdentified(self.boundOnIdentified);
|
|
288
|
+
self.waitForIdentSlot = self.peer.waitForIdentified(self.boundOnIdentified);
|
|
218
289
|
}
|
|
219
290
|
};
|
|
220
291
|
|
|
@@ -259,7 +330,8 @@ LazyRelayInReq.prototype.forwardTo =
|
|
|
259
330
|
function forwardTo(conn) {
|
|
260
331
|
var self = this;
|
|
261
332
|
|
|
262
|
-
self.outreq =
|
|
333
|
+
self.outreq = LazyRelayOutReq.alloc();
|
|
334
|
+
self.outreq.reset(conn, self);
|
|
263
335
|
|
|
264
336
|
var ttl = self.updateTTL(self.outreq.start);
|
|
265
337
|
if (!ttl || ttl < 0) {
|
|
@@ -315,7 +387,7 @@ function updateTTL(now) {
|
|
|
315
387
|
timeout = self.channel.maximumRelayTTL;
|
|
316
388
|
}
|
|
317
389
|
|
|
318
|
-
var res = self.reqFrame.bodyRW.lazy.
|
|
390
|
+
var res = self.reqFrame.bodyRW.lazy.poolWriteTTL(writeRes, timeout, self.reqFrame);
|
|
319
391
|
if (res.err) {
|
|
320
392
|
// TODO: wrap? protocol write error?
|
|
321
393
|
self.onError(res.err);
|
|
@@ -339,8 +411,10 @@ function onReadError(err) {
|
|
|
339
411
|
);
|
|
340
412
|
}
|
|
341
413
|
|
|
414
|
+
var conn = self.conn;
|
|
342
415
|
self.onError(err);
|
|
343
|
-
|
|
416
|
+
|
|
417
|
+
conn.resetAll(err);
|
|
344
418
|
};
|
|
345
419
|
|
|
346
420
|
LazyRelayInReq.prototype.onError =
|
|
@@ -351,6 +425,7 @@ function onError(err) {
|
|
|
351
425
|
self.logger.warn('dropping error from dead relay request', self.extendLogInfo({
|
|
352
426
|
error: err
|
|
353
427
|
}));
|
|
428
|
+
self.free();
|
|
354
429
|
return;
|
|
355
430
|
}
|
|
356
431
|
|
|
@@ -370,6 +445,8 @@ function onError(err) {
|
|
|
370
445
|
}));
|
|
371
446
|
|
|
372
447
|
self.reqContFrames.length = 0;
|
|
448
|
+
|
|
449
|
+
self.free();
|
|
373
450
|
};
|
|
374
451
|
|
|
375
452
|
LazyRelayInReq.prototype.sendErrorFrame =
|
|
@@ -391,6 +468,7 @@ function handleFrameLazily(frame) {
|
|
|
391
468
|
|
|
392
469
|
if (!self.alive) {
|
|
393
470
|
self.logger.warn('dropping frame from dead relay request', self.extendLogInfo({}));
|
|
471
|
+
self.free();
|
|
394
472
|
return;
|
|
395
473
|
}
|
|
396
474
|
|
|
@@ -518,6 +596,22 @@ function _observeCallReqContFrame(frame) {
|
|
|
518
596
|
};
|
|
519
597
|
|
|
520
598
|
function LazyRelayOutReq(conn, inreq) {
|
|
599
|
+
this.channel = null;
|
|
600
|
+
this.conn = null;
|
|
601
|
+
this.start = null;
|
|
602
|
+
this.remoteAddr = null;
|
|
603
|
+
this.logger = null;
|
|
604
|
+
this.inreq = null;
|
|
605
|
+
this.id = null;
|
|
606
|
+
this.serviceName = null;
|
|
607
|
+
this.callerName = null;
|
|
608
|
+
this.timeout = null;
|
|
609
|
+
this.operations = null;
|
|
610
|
+
this.timeHeapHandle = null;
|
|
611
|
+
this.alive = null;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
LazyRelayOutReq.prototype.reset = function reset(conn, inreq) {
|
|
521
615
|
this.channel = conn.channel;
|
|
522
616
|
this.conn = conn;
|
|
523
617
|
this.start = conn.timers.now();
|
|
@@ -530,7 +624,26 @@ function LazyRelayOutReq(conn, inreq) {
|
|
|
530
624
|
this.timeout = 0;
|
|
531
625
|
this.operations = null;
|
|
532
626
|
this.timeHeapHandle = null;
|
|
533
|
-
|
|
627
|
+
this.alive = true;
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
LazyRelayOutReq.prototype.clear = function clear() {
|
|
631
|
+
this.channel = null;
|
|
632
|
+
this.conn = null;
|
|
633
|
+
this.start = null;
|
|
634
|
+
this.remoteAddr = null;
|
|
635
|
+
this.logger = null;
|
|
636
|
+
this.inreq = null;
|
|
637
|
+
this.id = null;
|
|
638
|
+
this.serviceName = null;
|
|
639
|
+
this.callerName = null;
|
|
640
|
+
this.timeout = null;
|
|
641
|
+
this.operations = null;
|
|
642
|
+
this.timeHeapHandle = null;
|
|
643
|
+
this.alive = null;
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
ObjectPool.setup({Type: LazyRelayOutReq, maxSize: 200});
|
|
534
647
|
|
|
535
648
|
LazyRelayOutReq.prototype.type = 'tchannel.lazy.outgoing-request';
|
|
536
649
|
|
|
@@ -566,6 +679,11 @@ LazyRelayOutReq.prototype.emitError =
|
|
|
566
679
|
function emitError(err) {
|
|
567
680
|
var self = this;
|
|
568
681
|
|
|
682
|
+
// ObjectPool weird free() issue; bail early
|
|
683
|
+
if (!self.channel) {
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
|
|
569
687
|
var now = self.channel.timers.now();
|
|
570
688
|
var elapsed = now - self.start;
|
|
571
689
|
|
|
@@ -599,7 +717,16 @@ function emitError(err) {
|
|
|
599
717
|
self.inreq.circuit.state.onRequestError(err);
|
|
600
718
|
}
|
|
601
719
|
|
|
602
|
-
|
|
720
|
+
// We need to defer the inreq onError work, because we might be
|
|
721
|
+
// *syncronously* processing an error after an attempt to write to a
|
|
722
|
+
// socket. Otherwise, we might end up freeing the in/outreq pair before a
|
|
723
|
+
// handleFrameLazily has completed.
|
|
724
|
+
process.nextTick(deferInReqOnError);
|
|
725
|
+
function deferInReqOnError() {
|
|
726
|
+
if (self.inreq) {
|
|
727
|
+
self.inreq.onError(err);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
603
730
|
};
|
|
604
731
|
|
|
605
732
|
LazyRelayOutReq.prototype.logError =
|
|
@@ -613,6 +740,11 @@ LazyRelayOutReq.prototype.onTimeout =
|
|
|
613
740
|
function onTimeout(now) {
|
|
614
741
|
var self = this;
|
|
615
742
|
|
|
743
|
+
// ObjectPool weird free() issue; bail early
|
|
744
|
+
if (!self.conn) {
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
|
|
616
748
|
self.conn.ops.checkLastTimeoutTime(now);
|
|
617
749
|
self.conn.ops.popOutReq(self.id, self.extendLogInfo({
|
|
618
750
|
info: 'lazy out request timed out',
|
|
@@ -636,9 +768,15 @@ function handleFrameLazily(frame) {
|
|
|
636
768
|
// - v2.Types.ErrorResponse
|
|
637
769
|
var self = this;
|
|
638
770
|
|
|
771
|
+
// ObjectPool weird free() issue; bail early
|
|
772
|
+
if (!self.inreq) {
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
|
|
639
776
|
frame.setId(self.inreq.id);
|
|
640
777
|
self.inreq.conn.writeToSocket(frame.buffer);
|
|
641
778
|
if (frame.bodyRW.lazy.isFrameTerminal(frame)) {
|
|
779
|
+
self.alive = false;
|
|
642
780
|
self.conn.ops.popOutReq(self.id, self.extendLogInfo({
|
|
643
781
|
info: 'lazy relay request done',
|
|
644
782
|
relayDirection: 'out'
|
|
@@ -655,6 +793,11 @@ function handleFrameLazily(frame) {
|
|
|
655
793
|
self._observeErrorFrame(frame, now);
|
|
656
794
|
// } else { TODO: log
|
|
657
795
|
}
|
|
796
|
+
|
|
797
|
+
if (!self.alive && !self.inreq.alive) {
|
|
798
|
+
// Implicitly frees this because inreq.clear will free outreq
|
|
799
|
+
self.inreq.free();
|
|
800
|
+
}
|
|
658
801
|
};
|
|
659
802
|
|
|
660
803
|
LazyRelayOutReq.prototype._observeErrorFrame =
|
|
@@ -767,7 +910,7 @@ function _observeCallResFrame(frame, now) {
|
|
|
767
910
|
self.inreq.circuit.state.onRequestHealthy();
|
|
768
911
|
}
|
|
769
912
|
|
|
770
|
-
var res = frame.bodyRW.lazy.
|
|
913
|
+
var res = frame.bodyRW.lazy.poolReadCode(readRes, frame);
|
|
771
914
|
if (res.err) {
|
|
772
915
|
self.logger.error('failed to read error frame code', self.extendLogInfo({
|
|
773
916
|
error: res.err
|
|
@@ -775,8 +918,8 @@ function _observeCallResFrame(frame, now) {
|
|
|
775
918
|
return;
|
|
776
919
|
}
|
|
777
920
|
|
|
778
|
-
var
|
|
779
|
-
var ok =
|
|
921
|
+
var code = res.value;
|
|
922
|
+
var ok = code === 0;
|
|
780
923
|
|
|
781
924
|
if (ok) {
|
|
782
925
|
self.channel.emitFastStat(
|