electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 62e352a2a8e61ae930b6a09b1457d5419afea35c
parent b3ff173b4507e8325c65d607a4547320ba2c8798
Author: SomberNight <somber.night@protonmail.com>
Date:   Sun,  9 Dec 2018 20:04:42 +0100

network: don't let _maintain_sessions die from CancelledError

as then the network would get paralysed and no one can fix it

Diffstat:
Melectrum/network.py | 29+++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/electrum/network.py b/electrum/network.py @@ -197,7 +197,7 @@ class Network(PrintError): if not self.default_server: self.default_server = pick_random_server() - self.main_taskgroup = None + self.main_taskgroup = None # type: TaskGroup # locks self.restart_lock = asyncio.Lock() @@ -817,7 +817,7 @@ class Network(PrintError): async def _start(self): assert not self.main_taskgroup - self.main_taskgroup = SilentTaskGroup() + self.main_taskgroup = main_taskgroup = SilentTaskGroup() assert not self.interface and not self.interfaces assert not self.connecting and not self.server_queue self.print_error('starting network') @@ -831,7 +831,9 @@ class Network(PrintError): async def main(): try: await self._init_headers_file() - async with self.main_taskgroup as group: + # note: if a task finishes with CancelledError, that + # will NOT raise, and the group will keep the other tasks running + async with main_taskgroup as group: await group.spawn(self._maintain_sessions()) [await group.spawn(job) for job in self._jobs] except Exception as e: @@ -852,7 +854,7 @@ class Network(PrintError): await asyncio.wait_for(self.main_taskgroup.cancel_remaining(), timeout=2) except (asyncio.TimeoutError, asyncio.CancelledError) as e: self.print_error(f"exc during main_taskgroup cancellation: {repr(e)}") - self.main_taskgroup = None + self.main_taskgroup = None # type: TaskGroup self.interface = None # type: Interface self.interfaces = {} # type: Dict[str, Interface] self.connecting.clear() @@ -884,13 +886,11 @@ class Network(PrintError): await self.switch_to_interface(self.default_server) async def _maintain_sessions(self): - while True: - # launch already queued up new interfaces + async def launch_already_queued_up_new_interfaces(): while self.server_queue.qsize() > 0: server = self.server_queue.get() await self.main_taskgroup.spawn(self._run_new_interface(server)) - - # maybe queue new interfaces to be launched later + async def maybe_queue_new_interfaces_to_be_launched_later(): now = time.time() for i in range(self.num_server - len(self.interfaces) - len(self.connecting)): self._start_random_interface() @@ -898,13 +898,22 @@ class Network(PrintError): self.print_error('network: retrying connections') self.disconnected_servers = set([]) self.nodes_retry_time = now - - # main interface + async def maintain_main_interface(): await self._ensure_there_is_a_main_interface() if self.is_connected(): if self.config.is_fee_estimates_update_required(): await self.interface.group.spawn(self._request_fee_estimates, self.interface) + while True: + try: + await launch_already_queued_up_new_interfaces() + await maybe_queue_new_interfaces_to_be_launched_later() + await maintain_main_interface() + except asyncio.CancelledError: + # suppress spurious cancellations + group = self.main_taskgroup + if not group or group._closed: + raise await asyncio.sleep(0.1)