commit 5339e0054c6e473ec4b5858ea9bb11aeb37be109
parent de6f5a8e0357b201b5f0ffe20195b36cad66824d
Author: SomberNight <somber.night@protonmail.com>
Date: Wed, 10 Mar 2021 19:01:30 +0100
network.stop: clean-up
Diffstat:
2 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/electrum/network.py b/electrum/network.py
@@ -39,13 +39,14 @@ from concurrent import futures
import copy
import aiorpcx
-from aiorpcx import TaskGroup
+from aiorpcx import TaskGroup, ignore_after
from aiohttp import ClientResponse
from . import util
from .util import (log_exceptions, ignore_exceptions,
bfh, SilentTaskGroup, make_aiohttp_session, send_exception_to_crash_reporter,
- is_hash256_str, is_non_negative_integer, MyEncoder, NetworkRetryManager)
+ is_hash256_str, is_non_negative_integer, MyEncoder, NetworkRetryManager,
+ nullcontext)
from .bitcoin import COIN
from . import constants
from . import blockchain
@@ -1223,11 +1224,13 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
@log_exceptions
async def stop(self, *, full_shutdown: bool = True):
self.logger.info("stopping network")
- try:
- # note: cancel_remaining ~cannot be cancelled, it suppresses CancelledError
- await asyncio.wait_for(self.taskgroup.cancel_remaining(), timeout=1)
- except (asyncio.TimeoutError, asyncio.CancelledError) as e:
- self.logger.info(f"exc during taskgroup cancellation: {repr(e)}")
+ # timeout: if full_shutdown, it is up to the caller to time us out,
+ # otherwise if e.g. restarting due to proxy changes, we time out fast
+ async with (nullcontext() if full_shutdown else ignore_after(1)):
+ async with TaskGroup() as group:
+ await group.spawn(self.taskgroup.cancel_remaining())
+ if full_shutdown:
+ await group.spawn(self.stop_gossip(full_shutdown=full_shutdown))
self.taskgroup = None
self.interface = None
self.interfaces = {}
@@ -1235,8 +1238,6 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
self._closing_ifaces.clear()
if not full_shutdown:
util.trigger_callback('network_updated')
- if full_shutdown:
- await self.stop_gossip(full_shutdown=full_shutdown)
async def _ensure_there_is_a_main_interface(self):
if self.is_connected():
diff --git a/electrum/util.py b/electrum/util.py
@@ -1568,3 +1568,24 @@ def test_read_write_permissions(path) -> None:
raise IOError(e) from e
if echo != echo2:
raise IOError('echo sanity-check failed')
+
+
+class nullcontext:
+ """Context manager that does no additional processing.
+ This is a ~backport of contextlib.nullcontext from Python 3.10
+ """
+
+ def __init__(self, enter_result=None):
+ self.enter_result = enter_result
+
+ def __enter__(self):
+ return self.enter_result
+
+ def __exit__(self, *excinfo):
+ pass
+
+ async def __aenter__(self):
+ return self.enter_result
+
+ async def __aexit__(self, *excinfo):
+ pass