market cap fixes
This commit is contained in:
@ -1,11 +1,33 @@
|
||||
import logging
|
||||
import json
|
||||
import time
|
||||
import os
|
||||
import traceback
|
||||
from hyperliquid.info import Info
|
||||
from hyperliquid.utils import constants
|
||||
|
||||
from logging_utils import setup_logging
|
||||
|
||||
# --- Configuration for standalone error logging ---
|
||||
LOGS_DIR = "_logs"
|
||||
ERROR_LOG_FILE = os.path.join(LOGS_DIR, "live_market_errors.log")
|
||||
|
||||
def log_error(error_message: str, include_traceback: bool = True):
|
||||
"""A simple, robust file logger for any errors."""
|
||||
try:
|
||||
if not os.path.exists(LOGS_DIR):
|
||||
os.makedirs(LOGS_DIR)
|
||||
|
||||
with open(ERROR_LOG_FILE, 'a') as f:
|
||||
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
|
||||
f.write(f"--- ERROR at {timestamp} UTC ---\n")
|
||||
f.write(error_message + "\n")
|
||||
if include_traceback:
|
||||
f.write(traceback.format_exc() + "\n")
|
||||
f.write("="*50 + "\n")
|
||||
except Exception:
|
||||
print(f"CRITICAL: Failed to write to error log file: {error_message}", file=sys.stderr)
|
||||
|
||||
def on_message(message, shared_prices_dict):
|
||||
"""
|
||||
Callback function to process incoming 'allMids' messages and update the
|
||||
@ -14,36 +36,71 @@ def on_message(message, shared_prices_dict):
|
||||
try:
|
||||
if message.get("channel") == "allMids":
|
||||
new_prices = message.get("data", {}).get("mids", {})
|
||||
# Update the shared dictionary with the new price data
|
||||
shared_prices_dict.update(new_prices)
|
||||
except Exception as e:
|
||||
# It's important to log errors inside the process
|
||||
logging.error(f"Error in WebSocket on_message: {e}")
|
||||
log_error(f"Error in WebSocket on_message: {e}")
|
||||
|
||||
def start_live_feed(shared_prices_dict, log_level='off'):
|
||||
"""
|
||||
Main function for the WebSocket process. It takes a shared dictionary
|
||||
and continuously feeds it with live market data.
|
||||
Includes a watchdog to auto-reconnect on failure.
|
||||
"""
|
||||
setup_logging(log_level, 'LiveMarketFeed')
|
||||
|
||||
# The Info object manages the WebSocket connection.
|
||||
info = Info(constants.MAINNET_API_URL, skip_ws=False)
|
||||
|
||||
# We need to wrap the callback in a lambda to pass our shared dictionary
|
||||
info = None
|
||||
callback = lambda msg: on_message(msg, shared_prices_dict)
|
||||
|
||||
# Subscribe to the allMids channel
|
||||
subscription = {"type": "allMids"}
|
||||
info.subscribe(subscription, callback)
|
||||
logging.info("Subscribed to 'allMids' for live mark prices.")
|
||||
def connect_and_subscribe():
|
||||
"""Establishes a new WebSocket connection and subscribes to allMids."""
|
||||
try:
|
||||
logging.info("Connecting to Hyperliquid WebSocket...")
|
||||
# Ensure skip_ws=False to create the ws_manager
|
||||
new_info = Info(constants.MAINNET_API_URL, skip_ws=False)
|
||||
subscription = {"type": "allMids"}
|
||||
new_info.subscribe(subscription, callback)
|
||||
logging.info("WebSocket connected and subscribed to 'allMids'.")
|
||||
return new_info
|
||||
except Exception as e:
|
||||
log_error(f"Failed to connect to WebSocket: {e}")
|
||||
return None
|
||||
|
||||
info = connect_and_subscribe()
|
||||
|
||||
logging.info("Starting live price feed process. Press Ctrl+C in main app to stop.")
|
||||
|
||||
try:
|
||||
# The background thread in the SDK handles messages. This loop just keeps the process alive.
|
||||
while True:
|
||||
time.sleep(1)
|
||||
# --- Watchdog Logic ---
|
||||
time.sleep(15) # Check the connection every 15 seconds
|
||||
|
||||
if info is None or not info.ws_manager.is_running():
|
||||
# --- FIX: Log this critical failure to the persistent error log ---
|
||||
error_msg = "WebSocket connection lost or not running. Attempting to reconnect..."
|
||||
logging.warning(error_msg)
|
||||
log_error(error_msg, include_traceback=False) # Log it to the file
|
||||
|
||||
if info:
|
||||
try:
|
||||
info.ws_manager.stop() # Clean up old manager
|
||||
except Exception as e:
|
||||
log_error(f"Error stopping old ws_manager: {e}")
|
||||
|
||||
info = connect_and_subscribe()
|
||||
|
||||
if info is None:
|
||||
logging.error("Reconnect failed, will retry in 15s.")
|
||||
else:
|
||||
logging.info("Successfully reconnected to WebSocket.")
|
||||
else:
|
||||
logging.debug("Watchdog check: WebSocket connection is active.")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logging.info("Stopping WebSocket listener...")
|
||||
info.ws_manager.stop()
|
||||
except Exception as e:
|
||||
log_error(f"Live Market Feed process crashed: {e}")
|
||||
finally:
|
||||
if info and info.ws_manager:
|
||||
info.ws_manager.stop()
|
||||
logging.info("Listener stopped.")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user