83 lines
2.5 KiB
Python
83 lines
2.5 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
Example: External Factors Service using ServiceBase
|
||
|
|
"""
|
||
|
|
import asyncio
|
||
|
|
from service_base import ServiceBase, get_logger, run_scheduled
|
||
|
|
|
||
|
|
class ExFService(ServiceBase):
|
||
|
|
"""
|
||
|
|
External Factors Service - 0.5s aggressive oversampling
|
||
|
|
"""
|
||
|
|
def __init__(self):
|
||
|
|
super().__init__(
|
||
|
|
name='exf',
|
||
|
|
check_interval=30,
|
||
|
|
max_retries=3,
|
||
|
|
notify_systemd=True
|
||
|
|
)
|
||
|
|
self.indicators = {}
|
||
|
|
self.cycle_count = 0
|
||
|
|
|
||
|
|
async def run_cycle(self):
|
||
|
|
"""Main cycle - runs every 0.5s"""
|
||
|
|
self.cycle_count += 1
|
||
|
|
|
||
|
|
# Fetch indicators with retry
|
||
|
|
await self._fetch_with_retry('basis')
|
||
|
|
await self._fetch_with_retry('spread')
|
||
|
|
await self._fetch_with_retry('imbal_btc')
|
||
|
|
await self._fetch_with_retry('imbal_eth')
|
||
|
|
|
||
|
|
# Push to Hazelcast
|
||
|
|
await self._push_to_hz()
|
||
|
|
|
||
|
|
# Log every 100 cycles
|
||
|
|
if self.cycle_count % 100 == 0:
|
||
|
|
self.logger.info(f"Cycle {self.cycle_count}: indicators updated")
|
||
|
|
|
||
|
|
# Sleep for 0.5s (non-blocking)
|
||
|
|
await asyncio.sleep(0.5)
|
||
|
|
|
||
|
|
@ServiceBase.retry_with_backoff
|
||
|
|
async def _fetch_with_retry(self, indicator: str):
|
||
|
|
"""Fetch single indicator with automatic retry"""
|
||
|
|
# Your fetch logic here
|
||
|
|
self.indicators[indicator] = {'value': 0.0, 'timestamp': time.time()}
|
||
|
|
|
||
|
|
async def _push_to_hz(self):
|
||
|
|
"""Push to Hazelcast with retry"""
|
||
|
|
try:
|
||
|
|
# Your HZ push logic here
|
||
|
|
pass
|
||
|
|
except Exception as e:
|
||
|
|
self.logger.error(f"HZ push failed: {e}")
|
||
|
|
raise
|
||
|
|
|
||
|
|
async def health_check(self) -> bool:
|
||
|
|
"""Custom health check"""
|
||
|
|
# Check if indicators are fresh
|
||
|
|
now = time.time()
|
||
|
|
for name, data in self.indicators.items():
|
||
|
|
if now - data.get('timestamp', 0) > 2.0:
|
||
|
|
self.logger.warning(f"Stale indicator: {name}")
|
||
|
|
return False
|
||
|
|
return True
|
||
|
|
|
||
|
|
# Alternative: Simple scheduled function
|
||
|
|
def simple_exf_task():
|
||
|
|
"""Simple version without full service overhead"""
|
||
|
|
logger = get_logger('dolphin.exf.simple')
|
||
|
|
logger.info("Running ExF fetch")
|
||
|
|
# Your logic here
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
import time
|
||
|
|
|
||
|
|
# Option 1: Full service with all features
|
||
|
|
service = ExFService()
|
||
|
|
service.run()
|
||
|
|
|
||
|
|
# Option 2: Simple scheduled task
|
||
|
|
# run_scheduled(simple_exf_task, interval_seconds=0.5, name='exf')
|