From 0ca4be9af5364f4f47d06833ed59170ac271c4b6 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Tue, 4 May 2021 01:16:29 -0300 Subject: [PATCH 1/4] dont log full pages --- lbry/extras/daemon/exchange_rate_manager.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lbry/extras/daemon/exchange_rate_manager.py b/lbry/extras/daemon/exchange_rate_manager.py index b9ca80ba83..dddac741d2 100644 --- a/lbry/extras/daemon/exchange_rate_manager.py +++ b/lbry/extras/daemon/exchange_rate_manager.py @@ -86,7 +86,9 @@ async def get_rate(self): except asyncio.TimeoutError: log.warning("Timed out fetching exchange rate from %s.", self.name) except json.JSONDecodeError as e: - log.warning("Could not parse exchange rate response from %s: %s", self.name, e.doc) + msg = e.doc if '' not in e.doc else 'unexpected content type.' + log.warning("Could not parse exchange rate response from %s: %s", self.name, msg) + log.debug(msg) except InvalidExchangeRateResponseError as e: log.warning(str(e)) except Exception as e: From 839966f4fdca43bd4d73903ab4e80aa90b6768a3 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Tue, 4 May 2021 01:20:18 -0300 Subject: [PATCH 2/4] dont log full exceptions on simple connection errors --- lbry/extras/daemon/exchange_rate_manager.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lbry/extras/daemon/exchange_rate_manager.py b/lbry/extras/daemon/exchange_rate_manager.py index dddac741d2..283f6979b2 100644 --- a/lbry/extras/daemon/exchange_rate_manager.py +++ b/lbry/extras/daemon/exchange_rate_manager.py @@ -5,7 +5,7 @@ from statistics import median from decimal import Decimal from typing import Optional, Iterable, Type -from aiohttp.client_exceptions import ContentTypeError +from aiohttp.client_exceptions import ContentTypeError, ClientConnectionError from lbry.error import InvalidExchangeRateResponseError, CurrencyConversionError from lbry.utils import aiohttp_request from lbry.wallet.dewies import lbc_to_dewies @@ -91,6 +91,8 @@ async def get_rate(self): log.debug(msg) except InvalidExchangeRateResponseError as e: log.warning(str(e)) + except ClientConnectionError as e: + log.warning("Error trying to connect to exchange rate %s: %s", self.name, str(e)) except Exception as e: log.exception("Exchange rate error (%s from %s):", self.market, self.name) From 0c5ffb3b4fd2adbe766d3f40bbcd60211485ebe4 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Tue, 4 May 2021 01:40:57 -0300 Subject: [PATCH 3/4] don't fail when a single one go on maintenance and set completion event regardless of failures --- lbry/extras/daemon/exchange_rate_manager.py | 3 +- .../other/test_exchange_rate_manager.py | 29 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lbry/extras/daemon/exchange_rate_manager.py b/lbry/extras/daemon/exchange_rate_manager.py index 283f6979b2..bb62287963 100644 --- a/lbry/extras/daemon/exchange_rate_manager.py +++ b/lbry/extras/daemon/exchange_rate_manager.py @@ -79,7 +79,6 @@ async def get_rate(self): log.debug("Saving rate update %f for %s from %s", rate, self.market, self.name) self.rate = ExchangeRate(self.market, rate, int(time.time())) self.last_check = time.time() - self.event.set() return self.rate except asyncio.CancelledError: raise @@ -95,6 +94,8 @@ async def get_rate(self): log.warning("Error trying to connect to exchange rate %s: %s", self.name, str(e)) except Exception as e: log.exception("Exchange rate error (%s from %s):", self.market, self.name) + finally: + self.event.set() async def keep_updated(self): while True: diff --git a/tests/integration/other/test_exchange_rate_manager.py b/tests/integration/other/test_exchange_rate_manager.py index c8346f8ee2..6f584bfc79 100644 --- a/tests/integration/other/test_exchange_rate_manager.py +++ b/tests/integration/other/test_exchange_rate_manager.py @@ -1,6 +1,8 @@ +import asyncio +import logging from decimal import Decimal from lbry.testcase import AsyncioTestCase -from lbry.extras.daemon.exchange_rate_manager import ExchangeRate, ExchangeRateManager, FEEDS +from lbry.extras.daemon.exchange_rate_manager import ExchangeRate, ExchangeRateManager, FEEDS, MarketFeed class TestExchangeRateManager(AsyncioTestCase): @@ -12,13 +14,32 @@ async def test_exchange_rate_manager(self): self.assertFalse(feed.is_online) self.assertIsNone(feed.rate) await manager.wait() + failures = set() for feed in manager.market_feeds: - self.assertTrue(feed.is_online) - self.assertIsInstance(feed.rate, ExchangeRate) - # print(f'{feed.name} - {feed.market} - {feed.rate.spot}') + if feed.is_online: + self.assertIsInstance(feed.rate, ExchangeRate) + else: + failures.add(feed.name) + self.assertFalse(feed.has_rate) + self.assertLessEqual(len(failures), 1, f"feed failures: {failures}. Please check exchange rate feeds!") lbc = manager.convert_currency('USD', 'LBC', Decimal('1.0')) self.assertGreaterEqual(lbc, 2.0) self.assertLessEqual(lbc, 10.0) lbc = manager.convert_currency('BTC', 'LBC', Decimal('0.01')) self.assertGreaterEqual(lbc, 1_000) self.assertLessEqual(lbc, 4_000) + + async def test_it_handles_feed_being_offline(self): + class FakeFeed(MarketFeed): + name = "fake" + url = "http://impossi.bru" + manager = ExchangeRateManager((FakeFeed,)) + manager.start() + self.addCleanup(manager.stop) + for feed in manager.market_feeds: + self.assertFalse(feed.is_online) + self.assertIsNone(feed.rate) + await asyncio.wait_for(manager.wait(), 2) + for feed in manager.market_feeds: + self.assertFalse(feed.is_online) + self.assertFalse(feed.has_rate) From cbf58661d262c2018cf3bb0d3bc72ea47f0dc984 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Tue, 4 May 2021 01:43:51 -0300 Subject: [PATCH 4/4] for debug, it is always whole page --- lbry/extras/daemon/exchange_rate_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lbry/extras/daemon/exchange_rate_manager.py b/lbry/extras/daemon/exchange_rate_manager.py index bb62287963..5f92d80022 100644 --- a/lbry/extras/daemon/exchange_rate_manager.py +++ b/lbry/extras/daemon/exchange_rate_manager.py @@ -87,7 +87,7 @@ async def get_rate(self): except json.JSONDecodeError as e: msg = e.doc if '' not in e.doc else 'unexpected content type.' log.warning("Could not parse exchange rate response from %s: %s", self.name, msg) - log.debug(msg) + log.debug(e.doc) except InvalidExchangeRateResponseError as e: log.warning(str(e)) except ClientConnectionError as e: