Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions hathor/builder/cli_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def check_or_raise(self, condition: bool, message: str) -> None:
def create_manager(self, reactor: PosixReactorBase, args: Namespace) -> HathorManager:
import hathor
from hathor.conf import HathorSettings
from hathor.conf.get_settings import get_settings_filepath, get_settings_module
from hathor.conf.get_settings import get_settings_source
from hathor.daa import TestMode, _set_test_mode
from hathor.event.storage import EventMemoryStorage, EventRocksDBStorage, EventStorage
from hathor.event.websocket.factory import EventWebsocketFactory
Expand All @@ -74,8 +74,7 @@ def create_manager(self, reactor: PosixReactorBase, args: Namespace) -> HathorMa
settings = HathorSettings()

# only used for logging its location
settings_module = get_settings_module()
settings_source = settings_module.__file__ if settings_module is not None else get_settings_filepath()
settings_source = get_settings_source()

self.log = logger.new()
self.reactor = reactor
Expand Down
88 changes: 49 additions & 39 deletions hathor/conf/get_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@

import importlib
import os
from types import ModuleType
from typing import Optional
from typing import NamedTuple, Optional

from structlog import get_logger

Expand All @@ -24,8 +23,14 @@

logger = get_logger()

_settings_filepath: Optional[str] = None
_config_file: Optional[str] = None

class _SettingsMetadata(NamedTuple):
source: str
is_yaml: bool
settings: Settings


_settings_singleton: Optional[_SettingsMetadata] = None


def HathorSettings() -> Settings:
Expand All @@ -37,52 +42,57 @@ def HathorSettings() -> Settings:

If neither is set, or if the module import fails, the mainnet configuration is returned.
"""
settings_module = get_settings_module()

if settings_module is not None:
log = logger.new()
log.warn(
"Setting a config module via the 'HATHOR_CONFIG_FILE' env var will be deprecated soon. "
"Use the '--config-yaml' CLI option or the 'HATHOR_CONFIG_YAML' env var to set a yaml filepath instead."
)
settings = getattr(settings_module, 'SETTINGS')
assert isinstance(settings, Settings)
return settings
settings_module_filepath = os.environ.get('HATHOR_CONFIG_FILE')
if settings_module_filepath is not None:
return _load_settings_singleton(settings_module_filepath, is_yaml=False)

settings_filepath = get_settings_filepath()
settings_yaml_filepath = os.environ.get('HATHOR_CONFIG_YAML', conf.MAINNET_SETTINGS_FILEPATH)
return _load_settings_singleton(settings_yaml_filepath, is_yaml=True)

return Settings.from_yaml(filepath=settings_filepath)

def get_settings_source() -> str:
""" Returns the path of the settings module or YAML file that was loaded.

XXX: Will raise an assertion error if HathorSettings() wasn't used before.
"""
global _settings_singleton
assert _settings_singleton is not None, 'HathorSettings() not called before'
return _settings_singleton.source

def get_settings_module() -> Optional[ModuleType]:
global _config_file
# Import config file for network
config_file = os.environ.get('HATHOR_CONFIG_FILE')
if _config_file is None:
_config_file = config_file
elif _config_file != config_file:
raise Exception('loading config twice with a different file')

if not config_file:
return None
def _load_settings_singleton(source: str, *, is_yaml: bool) -> Settings:
global _settings_singleton

try:
module = importlib.import_module(config_file)
except ModuleNotFoundError:
default_file = 'hathor.conf.mainnet'
module = importlib.import_module(default_file)
if _settings_singleton is not None:
if _settings_singleton.is_yaml != is_yaml:
raise Exception('loading config twice with a different file type')
if _settings_singleton.source != source:
raise Exception('loading config twice with a different file')

return module
return _settings_singleton.settings

settings_loader = _load_yaml_settings if is_yaml else _load_module_settings
_settings_singleton = _SettingsMetadata(
source=source,
is_yaml=is_yaml,
settings=settings_loader(source)
)

def get_settings_filepath() -> str:
global _settings_filepath
return _settings_singleton.settings

new_settings_filepath = os.environ.get('HATHOR_CONFIG_YAML', conf.MAINNET_SETTINGS_FILEPATH)

if _settings_filepath is not None and _settings_filepath != new_settings_filepath:
raise Exception('loading config twice with a different file')
def _load_module_settings(module_path: str) -> Settings:
log = logger.new()
log.warn(
"Setting a config module via the 'HATHOR_CONFIG_FILE' env var will be deprecated soon. "
"Use the '--config-yaml' CLI option or the 'HATHOR_CONFIG_YAML' env var to set a yaml filepath instead."
)
settings_module = importlib.import_module(module_path)
settings = getattr(settings_module, 'SETTINGS')
assert isinstance(settings, Settings)
return settings

_settings_filepath = new_settings_filepath

return new_settings_filepath
def _load_yaml_settings(filepath: str) -> Settings:
return Settings.from_yaml(filepath=filepath)