refactor: use metaclass for Singleton in FiatConverter
This commit is contained in:
@@ -5,7 +5,6 @@ e.g BTC to USD
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from requests.exceptions import RequestException
|
from requests.exceptions import RequestException
|
||||||
|
|
||||||
@@ -13,6 +12,7 @@ from freqtrade.constants import SUPPORTED_FIAT, Config
|
|||||||
from freqtrade.mixins.logging_mixin import LoggingMixin
|
from freqtrade.mixins.logging_mixin import LoggingMixin
|
||||||
from freqtrade.util import FtTTLCache
|
from freqtrade.util import FtTTLCache
|
||||||
from freqtrade.util.coin_gecko import FtCoinGeckoApi
|
from freqtrade.util.coin_gecko import FtCoinGeckoApi
|
||||||
|
from freqtrade.util.singleton import SingletonMeta
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -32,26 +32,16 @@ coingecko_mapping = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CryptoToFiatConverter(LoggingMixin):
|
class CryptoToFiatConverter(LoggingMixin, metaclass=SingletonMeta):
|
||||||
"""
|
"""
|
||||||
Main class to initiate Crypto to FIAT.
|
Main class to initiate Crypto to FIAT.
|
||||||
This object contains a list of pair Crypto, FIAT
|
This object contains a list of pair Crypto, FIAT
|
||||||
This object is also a Singleton
|
This object is also a Singleton
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__instance = None
|
|
||||||
|
|
||||||
_coinlistings: list[dict] = []
|
_coinlistings: list[dict] = []
|
||||||
_backoff: float = 0.0
|
_backoff: float = 0.0
|
||||||
|
|
||||||
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
|
|
||||||
"""
|
|
||||||
Singleton pattern to ensure only one instance is created.
|
|
||||||
"""
|
|
||||||
if not cls.__instance:
|
|
||||||
cls.__instance = super().__new__(cls)
|
|
||||||
return cls.__instance
|
|
||||||
|
|
||||||
def __init__(self, config: Config) -> None:
|
def __init__(self, config: Config) -> None:
|
||||||
# Timeout: 6h
|
# Timeout: 6h
|
||||||
self._pair_price: FtTTLCache = FtTTLCache(maxsize=500, ttl=6 * 60 * 60)
|
self._pair_price: FtTTLCache = FtTTLCache(maxsize=500, ttl=6 * 60 * 60)
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
class SingletonMeta(type):
|
||||||
|
"""
|
||||||
|
A thread-safe implementation of Singleton.
|
||||||
|
Use as metaclass to create singleton classes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_instances: dict = {}
|
||||||
|
|
||||||
|
def __call__(cls, *args: Any, **kwargs: Any) -> Any:
|
||||||
|
if cls not in cls._instances:
|
||||||
|
instance = super().__call__(*args, **kwargs)
|
||||||
|
cls._instances[cls] = instance
|
||||||
|
return cls._instances[cls]
|
||||||
@@ -12,6 +12,12 @@ from freqtrade.util.coin_gecko import FtCoinGeckoApi
|
|||||||
from tests.conftest import log_has, log_has_re
|
from tests.conftest import log_has, log_has_re
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def reset_singleton_instance():
|
||||||
|
# Reset the singleton instance before each test
|
||||||
|
CryptoToFiatConverter._instances = {}
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_convert_is_singleton():
|
def test_fiat_convert_is_singleton():
|
||||||
fiat_convert = CryptoToFiatConverter({"a": 22})
|
fiat_convert = CryptoToFiatConverter({"a": 22})
|
||||||
fiat_convert2 = CryptoToFiatConverter({})
|
fiat_convert2 = CryptoToFiatConverter({})
|
||||||
|
|||||||
Reference in New Issue
Block a user