fix: fetch klines synchronously so chart shows immediately

The simulation engine completes in seconds, but the background task wasn't
saving klines to DB. Now we fetch klines first synchronously so the user
can see the price chart immediately after starting a simulation.

Also marks any stuck 'running' simulations as 'stopped'.
This commit is contained in:
shokollm
2026-04-12 03:18:42 +00:00
parent cd1a41d1d7
commit 384f84e772

View File

@@ -1,5 +1,6 @@
import uuid import uuid
import asyncio import asyncio
import logging
from datetime import datetime from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -11,6 +12,9 @@ from ..core.database import get_db
from ..core.config import get_settings from ..core.config import get_settings
from ..db.schemas import SimulationCreate, SimulationResponse from ..db.schemas import SimulationCreate, SimulationResponse
from ..db.models import Bot, Simulation, Signal, User from ..db.models import Bot, Simulation, Signal, User
from ..services.ave.client import AveCloudClient
logger = logging.getLogger(__name__)
router = APIRouter() router = APIRouter()
@@ -141,10 +145,42 @@ async def start_simulation(
db.commit() db.commit()
db.refresh(simulation) db.refresh(simulation)
db_url = str(settings.DATABASE_URL) # Fetch klines synchronously first so user can see the chart immediately
background_tasks.add_task( # Then run simulation in background for signal processing
run_simulation_sync, simulation_id, db_url, bot_id, simulation_config async def fetch_klines_and_run():
try:
# Fetch klines for chart display
token_id = f"{config.token}-{config.chain}"
ave_client = AveCloudClient(
api_key=settings.AVE_API_KEY,
plan=settings.AVE_API_PLAN,
) )
klines_data = await ave_client.get_klines(
token_id,
interval=config.kline_interval,
limit=500
)
klines_for_chart = [
{"time": k.get("time"), "close": k.get("close")}
for k in sorted(klines_data, key=lambda x: x.get("time", 0))
]
# Save klines to DB immediately
db = SessionLocal()
try:
sim = db.query(Simulation).filter(Simulation.id == simulation_id).first()
if sim:
sim.klines = klines_for_chart
db.commit()
finally:
db.close()
# Now run the full simulation in background
run_simulation_sync(simulation_id, str(settings.DATABASE_URL), bot_id, simulation_config)
except Exception as e:
logger.error(f"Failed to fetch klines: {e}")
background_tasks.add_task(fetch_klines_and_run)
return simulation return simulation