@@ -80,18 +80,32 @@ class JsonRPC {
80
80
void _sendNextAvailableRequest () {
81
81
_requestQueue.nextIncompleteReq.then ((req) {
82
82
if (req != null ) {
83
- // \r\n required by electrumx server
84
- if (_socket != null ) {
83
+ if (! Prefs .instance.useTor) {
84
+ if (_socket == null ) {
85
+ Logging .instance.log (
86
+ "JsonRPC _sendNextAvailableRequest attempted with"
87
+ " _socket=null on $host :$port " ,
88
+ level: LogLevel .Error ,
89
+ );
90
+ }
91
+ // \r\n required by electrumx server
85
92
_socket! .write ('${req .jsonRequest }\r\n ' );
86
- }
87
- if (_socksSocket != null ) {
88
- _socksSocket! .write ('${req .jsonRequest }\r\n ' );
93
+ } else {
94
+ if (_socksSocket == null ) {
95
+ Logging .instance.log (
96
+ "JsonRPC _sendNextAvailableRequest attempted with"
97
+ " _socksSocket=null on $host :$port " ,
98
+ level: LogLevel .Error ,
99
+ );
100
+ }
101
+ // \r\n required by electrumx server
102
+ _socksSocket? .write ('${req .jsonRequest }\r\n ' );
89
103
}
90
104
91
105
// TODO different timeout length?
92
106
req.initiateTimeout (
93
107
onTimedOut: () {
94
- _requestQueue. remove (req);
108
+ _onReqCompleted (req);
95
109
},
96
110
);
97
111
}
@@ -109,7 +123,7 @@ class JsonRPC {
109
123
"JsonRPC request: opening socket $host :$port " ,
110
124
level: LogLevel .Info ,
111
125
);
112
- await connect ().timeout (requestTimeout, onTimeout: () {
126
+ await _connect ().timeout (requestTimeout, onTimeout: () {
113
127
throw Exception ("Request timeout: $jsonRpcRequest " );
114
128
});
115
129
}
@@ -119,7 +133,7 @@ class JsonRPC {
119
133
"JsonRPC request: opening SOCKS socket to $host :$port " ,
120
134
level: LogLevel .Info ,
121
135
);
122
- await connect ().timeout (requestTimeout, onTimeout: () {
136
+ await _connect ().timeout (requestTimeout, onTimeout: () {
123
137
throw Exception ("Request timeout: $jsonRpcRequest " );
124
138
});
125
139
}
@@ -156,23 +170,42 @@ class JsonRPC {
156
170
return future;
157
171
}
158
172
159
- Future <void > disconnect ({required String reason}) async {
160
- await _requestMutex.protect (() async {
161
- await _subscription? .cancel ();
162
- _subscription = null ;
163
- _socket? .destroy ();
164
- _socket = null ;
165
- await _socksSocket? .close ();
166
- _socksSocket = null ;
167
-
168
- // clean up remaining queue
169
- await _requestQueue.completeRemainingWithError (
170
- "JsonRPC disconnect() called with reason: \" $reason \" " ,
171
- );
172
- });
173
+ /// DO NOT set [ignoreMutex] to true unless fully aware of the consequences
174
+ Future <void > disconnect ({
175
+ required String reason,
176
+ bool ignoreMutex = false ,
177
+ }) async {
178
+ if (ignoreMutex) {
179
+ await _disconnectHelper (reason: reason);
180
+ } else {
181
+ await _requestMutex.protect (() async {
182
+ await _disconnectHelper (reason: reason);
183
+ });
184
+ }
185
+ }
186
+
187
+ Future <void > _disconnectHelper ({required String reason}) async {
188
+ await _subscription? .cancel ();
189
+ _subscription = null ;
190
+ _socket? .destroy ();
191
+ _socket = null ;
192
+ await _socksSocket? .close ();
193
+ _socksSocket = null ;
194
+
195
+ // clean up remaining queue
196
+ await _requestQueue.completeRemainingWithError (
197
+ "JsonRPC disconnect() called with reason: \" $reason \" " ,
198
+ );
173
199
}
174
200
175
- Future <void > connect () async {
201
+ Future <void > _connect () async {
202
+ // ignore mutex is set to true here as _connect is already called within
203
+ // the mutex.protect block. Setting to false here leads to a deadlock
204
+ await disconnect (
205
+ reason: "New connection requested" ,
206
+ ignoreMutex: true ,
207
+ );
208
+
176
209
if (! Prefs .instance.useTor) {
177
210
if (useSSL) {
178
211
_socket = await SecureSocket .connect (
@@ -352,17 +385,20 @@ class _JsonRPCRequest {
352
385
}
353
386
354
387
void initiateTimeout ({
355
- VoidCallback ? onTimedOut,
388
+ required VoidCallback onTimedOut,
356
389
}) {
357
390
Future <void >.delayed (requestTimeout).then ((_) {
358
391
if (! isComplete) {
359
- try {
360
- throw JsonRpcException ("_JsonRPCRequest timed out: $jsonRequest " );
361
- } catch (e, s) {
362
- completer.completeError (e, s);
363
- onTimedOut? .call ();
364
- }
392
+ completer.complete (
393
+ JsonRPCResponse (
394
+ data: null ,
395
+ exception: JsonRpcException (
396
+ "_JsonRPCRequest timed out: $jsonRequest " ,
397
+ ),
398
+ ),
399
+ );
365
400
}
401
+ onTimedOut.call ();
366
402
});
367
403
}
368
404
@@ -375,14 +411,3 @@ class JsonRPCResponse {
375
411
376
412
JsonRPCResponse ({this .data, this .exception});
377
413
}
378
-
379
- bool isIpAddress (String host) {
380
- try {
381
- // if the string can be parsed into an InternetAddress, it's an IP.
382
- InternetAddress (host);
383
- return true ;
384
- } catch (e) {
385
- // if parsing fails, it's not an IP.
386
- return false ;
387
- }
388
- }
0 commit comments