Add configurable throttle mechanism

This commit is contained in:
gcarq 2017-11-11 16:47:19 +01:00
parent 8f817a3634
commit d3b3370f23
4 changed files with 56 additions and 7 deletions

View File

@ -34,5 +34,8 @@
"token": "token",
"chat_id": "chat_id"
},
"initial_state": "running"
"initial_state": "running",
"internals": {
"process_throttle_secs": 5
}
}

View File

@ -13,7 +13,7 @@ from jsonschema import validate
from freqtrade import __version__, exchange, persistence
from freqtrade.analyze import get_buy_signal
from freqtrade.misc import CONF_SCHEMA, State, get_state, update_state, build_arg_parser
from freqtrade.misc import CONF_SCHEMA, State, get_state, update_state, build_arg_parser, throttle
from freqtrade.persistence import Trade
from freqtrade.rpc import telegram
@ -280,14 +280,14 @@ def main():
# Load and validate configuration
with open(args.config) as file:
_CONF = json.load(file)
if 'internals' not in _CONF:
_CONF['internals'] = {}
logger.info('Validating configuration ...')
validate(_CONF, CONF_SCHEMA)
# Initialize all modules and start main loop
init(_CONF)
old_state = get_state()
logger.info('Initial State: %s', old_state)
telegram.send_msg('*Status:* `{}`'.format(old_state.name.lower()))
old_state = None
while True:
new_state = get_state()
# Log state transition
@ -298,8 +298,7 @@ def main():
if new_state == State.STOPPED:
time.sleep(1)
elif new_state == State.RUNNING:
_process()
time.sleep(5)
throttle(_process, min_secs=_CONF['internals'].get('process_throttle_secs', 5))
old_state = new_state

View File

@ -1,11 +1,15 @@
import argparse
import enum
import logging
from typing import Any, Callable
import time
from wrapt import synchronized
from freqtrade import __version__
logger = logging.getLogger(__name__)
class State(enum.Enum):
RUNNING = 0
@ -36,6 +40,23 @@ def get_state() -> State:
return _STATE
def throttle(func: Callable[..., Any], min_secs: float, *args, **kwargs) -> Any:
"""
Throttles the given callable that it
takes at least `min_secs` to finish execution.
:param func: Any callable
:param min_secs: minimum execution time in seconds
:return: Any
"""
start = time.time()
result = func(*args, **kwargs)
end = time.time()
duration = max(min_secs - (end - start), 0.0)
logger.debug('Throttling %s for %.2f seconds', func.__name__, duration)
time.sleep(duration)
return result
def build_arg_parser() -> argparse.ArgumentParser:
""" Builds and returns an ArgumentParser instance """
parser = argparse.ArgumentParser(
@ -104,6 +125,12 @@ CONF_SCHEMA = {
'required': ['enabled', 'token', 'chat_id']
},
'initial_state': {'type': 'string', 'enum': ['running', 'stopped']},
'internals': {
'type': 'object',
'properties': {
'process_throttle_secs': {'type': 'number'}
}
}
},
'definitions': {
'exchange': {

View File

@ -0,0 +1,20 @@
# pragma pylint: disable=missing-docstring
import time
from freqtrade.misc import throttle
def test_throttle():
def func():
return 42
start = time.time()
result = throttle(func, 0.1)
end = time.time()
assert result == 42
assert end - start > 0.1
result = throttle(func, -1)
assert result == 42