diff --git a/torba/tests/client_tests/integration/test_network.py b/torba/tests/client_tests/integration/test_network.py index cc5aef955..e4465dff9 100644 --- a/torba/tests/client_tests/integration/test_network.py +++ b/torba/tests/client_tests/integration/test_network.py @@ -29,6 +29,7 @@ class ReconnectTests(IntegrationTestCase): await asyncio.wait_for(self.on_transaction_id(sendtxid), 1.0) # mempool await self.blockchain.generate(1) await self.on_transaction_id(sendtxid) # confirmed + self.assertLess(self.ledger.network.client.latency, 1) # latency properly set lower, we are fine await self.assertBalance(self.account, '1.1337') # is it real? are we rich!? let me see this tx... @@ -37,6 +38,7 @@ class ReconnectTests(IntegrationTestCase): self.ledger.network.client.connection_lost(Exception()) with self.assertRaises((asyncio.TimeoutError, asyncio.CancelledError)): await d + self.assertGreater(self.ledger.network.client.latency, 1000) # latency skyrockets as it failed # rich but offline? no way, no water, let's retry with self.assertRaisesRegex(ConnectionError, 'connection is not available'): await self.ledger.network.get_transaction(sendtxid) diff --git a/torba/torba/client/basenetwork.py b/torba/torba/client/basenetwork.py index fe166ba4f..176740a15 100644 --- a/torba/torba/client/basenetwork.py +++ b/torba/torba/client/basenetwork.py @@ -74,6 +74,7 @@ class ClientSession(BaseClientSession): controller.add(request.args) def connection_lost(self, exc): + log.debug("Connection lost: %s:%d", *self.server) super().connection_lost(exc) self.latency = 1 << 32 self._on_disconnect_controller.add(True) @@ -136,10 +137,10 @@ class BaseNetwork: return self.client and not self.client.is_closing() def rpc(self, list_or_method, args): + fastest = self.session_pool.fastest_session + if fastest is not None and self.client != fastest: + self.switch_event.set() if self.is_connected: - fastest = self.session_pool.fastest_session - if self.client != fastest: - self.switch_event.set() return self.client.send_request(list_or_method, args) else: raise ConnectionError("Attempting to send rpc request when connection is not available.") diff --git a/torba/torba/rpc/jsonrpc.py b/torba/torba/rpc/jsonrpc.py index 5e908cd02..282b20df0 100644 --- a/torba/torba/rpc/jsonrpc.py +++ b/torba/torba/rpc/jsonrpc.py @@ -745,9 +745,10 @@ class JSONRPCConnection(object): self._protocol = item return self.receive_message(message) - def cancel_pending_requests(self): - """Cancel all pending requests.""" - exception = CancelledError() + def time_out_pending_requests(self): + """Times out all pending requests.""" + # this used to be CancelledError, but thats confusing as in are we closing the whole sdk or failing? + exception = TimeoutError() for request, event in self._requests.values(): event.result = exception event.set() diff --git a/torba/torba/rpc/session.py b/torba/torba/rpc/session.py index 2de40b88c..4e0295cdb 100644 --- a/torba/torba/rpc/session.py +++ b/torba/torba/rpc/session.py @@ -456,7 +456,7 @@ class RPCSession(SessionBase): def connection_lost(self, exc): # Cancel pending requests and message processing - self.connection.cancel_pending_requests() + self.connection.time_out_pending_requests() super().connection_lost(exc) # External API