Browse Source

network.best_effort_reliable: use curio APIs instead of asyncio

master
SomberNight 5 years ago
parent
commit
24e4aa3ab9
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 20
      electrum/network.py

20
electrum/network.py

@ -37,6 +37,7 @@ import traceback
import concurrent import concurrent
from concurrent import futures from concurrent import futures
import copy import copy
import functools
import aiorpcx import aiorpcx
from aiorpcx import TaskGroup, ignore_after from aiorpcx import TaskGroup, ignore_after
@ -829,24 +830,21 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
return True return True
def best_effort_reliable(func): def best_effort_reliable(func):
@functools.wraps(func)
async def make_reliable_wrapper(self: 'Network', *args, **kwargs): async def make_reliable_wrapper(self: 'Network', *args, **kwargs):
for i in range(10): for i in range(10):
iface = self.interface iface = self.interface
# retry until there is a main interface # retry until there is a main interface
if not iface: if not iface:
try: async with ignore_after(1):
await asyncio.wait_for(self.default_server_changed_event.wait(), 1) await self.default_server_changed_event.wait()
except asyncio.TimeoutError:
pass
continue # try again continue # try again
assert iface.ready.done(), "interface not ready yet" assert iface.ready.done(), "interface not ready yet"
# try actual request # try actual request
success_fut = asyncio.ensure_future(func(self, *args, **kwargs))
await asyncio.wait([success_fut, iface.got_disconnected.wait()], return_when=asyncio.FIRST_COMPLETED)
if success_fut.done() and not success_fut.cancelled():
if success_fut.exception():
try: try:
raise success_fut.exception() async with TaskGroup(wait=any) as group:
task = await group.spawn(func(self, *args, **kwargs))
await group.spawn(iface.got_disconnected.wait())
except RequestTimedOut: except RequestTimedOut:
await iface.close() await iface.close()
await iface.got_disconnected.wait() await iface.got_disconnected.wait()
@ -857,12 +855,14 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
await iface.close() await iface.close()
await iface.got_disconnected.wait() await iface.got_disconnected.wait()
continue # try again continue # try again
return success_fut.result() if task.done() and not task.cancelled():
return task.result()
# otherwise; try again # otherwise; try again
raise BestEffortRequestFailed('no interface to do request on... gave up.') raise BestEffortRequestFailed('no interface to do request on... gave up.')
return make_reliable_wrapper return make_reliable_wrapper
def catch_server_exceptions(func): def catch_server_exceptions(func):
@functools.wraps(func)
async def wrapper(self, *args, **kwargs): async def wrapper(self, *args, **kwargs):
try: try:
return await func(self, *args, **kwargs) return await func(self, *args, **kwargs)

Loading…
Cancel
Save