chart data loading

This commit is contained in:
2026-03-24 21:37:49 -04:00
parent f6bd22a8ef
commit c76887ab92
65 changed files with 6350 additions and 713 deletions

View File

@@ -13,6 +13,11 @@ import { WebSocketHandler } from './channels/websocket-handler.js';
import { TelegramHandler } from './channels/telegram-handler.js';
import { KubernetesClient } from './k8s/client.js';
import { ContainerManager } from './k8s/container-manager.js';
import { ZMQRelayClient } from './clients/zmq-relay-client.js';
import { IcebergClient } from './clients/iceberg-client.js';
import { OHLCService } from './services/ohlc-service.js';
import { SymbolIndexService } from './services/symbol-index-service.js';
import { SymbolRoutes } from './routes/symbol-routes.js';
// Catch unhandled promise rejections for better debugging
process.on('unhandledRejection', (reason: any, promise) => {
@@ -114,11 +119,19 @@ function loadConfig() {
iceberg: {
catalogUri: configData.iceberg?.catalog_uri || process.env.ICEBERG_CATALOG_URI || 'http://iceberg-catalog:8181',
namespace: configData.iceberg?.namespace || process.env.ICEBERG_NAMESPACE || 'gateway',
ohlcCatalogUri: configData.iceberg?.ohlc_catalog_uri || process.env.ICEBERG_OHLC_CATALOG_URI,
ohlcNamespace: configData.iceberg?.ohlc_namespace || process.env.ICEBERG_OHLC_NAMESPACE || 'trading',
s3Endpoint: configData.iceberg?.s3_endpoint || process.env.S3_ENDPOINT,
s3AccessKey: secretsData.iceberg?.s3_access_key || process.env.S3_ACCESS_KEY,
s3SecretKey: secretsData.iceberg?.s3_secret_key || process.env.S3_SECRET_KEY,
},
// Relay configuration (for historical data)
relay: {
requestEndpoint: configData.relay?.request_endpoint || process.env.RELAY_REQUEST_ENDPOINT || 'tcp://relay:5559',
notificationEndpoint: configData.relay?.notification_endpoint || process.env.RELAY_NOTIFICATION_ENDPOINT || 'tcp://relay:5558',
},
// Embedding configuration (for RAG)
embedding: {
provider: (configData.embedding?.provider || process.env.EMBEDDING_PROVIDER || 'ollama') as 'ollama' | 'openai' | 'anthropic' | 'local' | 'voyage' | 'cohere' | 'none',
@@ -224,10 +237,18 @@ const qdrantClient = new QdrantClient(config.qdrant, app.log);
// Initialize Iceberg client (for durable storage)
// const icebergClient = new IcebergClient(config.iceberg, app.log);
// Initialize ZMQ Relay client (for historical data)
// Note: onMetadataUpdate callback will be set after symbolIndexService is initialized
const zmqRelayClient = new ZMQRelayClient({
relayRequestEndpoint: config.relay.requestEndpoint,
relayNotificationEndpoint: config.relay.notificationEndpoint,
}, app.log);
app.log.info({
redis: config.redisUrl,
qdrant: config.qdrant.url,
iceberg: config.iceberg.catalogUri,
relay: config.relay.requestEndpoint,
embeddingProvider: config.embedding.provider,
}, 'Harness storage clients configured');
@@ -280,12 +301,32 @@ const eventRouter = new EventRouter({
});
app.log.debug('Event router initialized');
// Initialize OHLC service (optional - only if relay is available)
let ohlcService: OHLCService | undefined;
try {
const icebergClient = new IcebergClient(config.iceberg, app.log);
ohlcService = new OHLCService({
icebergClient,
relayClient: zmqRelayClient,
logger: app.log,
});
app.log.info('OHLC service initialized');
} catch (error) {
app.log.warn({ error }, 'Failed to initialize OHLC service - historical data will not be available');
}
// Initialize Symbol Index Service (deferred to after server starts)
let symbolIndexService: SymbolIndexService | undefined;
// Initialize channel handlers
const websocketHandler = new WebSocketHandler({
authenticator,
containerManager,
providerConfig: config.providerConfig,
sessionRegistry,
eventSubscriber,
ohlcService, // Optional
symbolIndexService, // Optional
});
app.log.debug('WebSocket handler initialized');
@@ -317,6 +358,13 @@ app.log.debug('Registering websocket handler...');
websocketHandler.register(app);
app.log.debug('Registering telegram handler...');
telegramHandler.register(app);
// Register symbol routes (service may not be ready yet, but routes will handle this)
app.log.debug('Registering symbol routes...');
const getSymbolService = () => symbolIndexService;
const symbolRoutes = new SymbolRoutes({ getSymbolIndexService: getSymbolService });
symbolRoutes.register(app);
app.log.debug('All routes registered');
// Health check
@@ -408,6 +456,11 @@ const shutdown = async () => {
await eventSubscriber.stop();
await eventRouter.stop();
// Close ZMQ relay client
if (zmqRelayClient.isConnected()) {
await zmqRelayClient.close();
}
// Disconnect Redis
redis.disconnect();
@@ -433,6 +486,15 @@ try {
await redis.connect();
app.log.info('Redis connected');
// Connect to ZMQ Relay
app.log.debug('Connecting to ZMQ Relay...');
try {
await zmqRelayClient.connect();
app.log.info('ZMQ Relay connected');
} catch (error) {
app.log.warn({ error }, 'ZMQ Relay connection failed - historical data will not be available');
}
// Initialize Qdrant collection
app.log.debug('Initializing Qdrant...');
try {
@@ -496,6 +558,34 @@ try {
},
'Gateway server started'
);
// Initialize Symbol Index Service (after server is running)
// This is done asynchronously to not block server startup
(async () => {
try {
const icebergClient = new IcebergClient(config.iceberg, app.log);
const indexService = new SymbolIndexService({
icebergClient,
logger: app.log,
});
await indexService.initialize();
symbolIndexService = indexService;
// Update websocket handler's config so it can use the service
(websocketHandler as any).config.symbolIndexService = indexService;
// Configure ZMQ relay to reload symbol metadata on updates
(zmqRelayClient as any).config.onMetadataUpdate = async () => {
app.log.info('Reloading symbol metadata from Iceberg');
await indexService.initialize();
app.log.info({ stats: indexService.getStats() }, 'Symbol metadata reloaded');
};
app.log.info({ stats: symbolIndexService.getStats() }, 'Symbol index service initialized');
} catch (error) {
app.log.warn({ error }, 'Failed to initialize symbol index service - symbol search will not be available');
}
})();
} catch (error) {
app.log.error({ error }, 'Failed to start server');
process.exit(1);