config changes to make it not async
This commit is contained in:
parent
24680e403d
commit
92d4b90987
5 changed files with 131 additions and 13 deletions
8
.env
8
.env
|
|
@ -164,3 +164,11 @@ TZ=UTC
|
||||||
APP_NAME="Stock Bot Platform"
|
APP_NAME="Stock Bot Platform"
|
||||||
APP_VERSION=1.0.0
|
APP_VERSION=1.0.0
|
||||||
APP_DESCRIPTION="Advanced Stock Trading and Analysis Platform"
|
APP_DESCRIPTION="Advanced Stock Trading and Analysis Platform"
|
||||||
|
|
||||||
|
# PostgreSQL
|
||||||
|
DATABASE_POSTGRES_HOST=localhost
|
||||||
|
DATABASE_POSTGRES_PORT=5432
|
||||||
|
DATABASE_POSTGRES_DATABASE=trading_bot
|
||||||
|
DATABASE_POSTGRES_USER=trading_user
|
||||||
|
DATABASE_POSTGRES_PASSWORD=trading_pass_dev
|
||||||
|
EOF < /dev/null
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
/**
|
|
||||||
* Data Service - Market data ingestion service
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Framework imports
|
// Framework imports
|
||||||
import { Hono } from 'hono';
|
import { Hono } from 'hono';
|
||||||
import { cors } from 'hono/cors';
|
import { cors } from 'hono/cors';
|
||||||
|
import { initializeConfigSync } from '@stock-bot/config';
|
||||||
// Library imports
|
// Library imports
|
||||||
import { initializeServiceConfig } from '@stock-bot/config';
|
|
||||||
import { getLogger, setLoggerConfig, shutdownLoggers } from '@stock-bot/logger';
|
import { getLogger, setLoggerConfig, shutdownLoggers } from '@stock-bot/logger';
|
||||||
import { connectMongoDB } from '@stock-bot/mongodb-client';
|
import { connectMongoDB } from '@stock-bot/mongodb-client';
|
||||||
import { connectPostgreSQL } from '@stock-bot/postgres-client';
|
import { connectPostgreSQL } from '@stock-bot/postgres-client';
|
||||||
|
|
@ -16,17 +12,14 @@ import { ProxyManager } from '@stock-bot/utils';
|
||||||
// Local imports
|
// Local imports
|
||||||
import { exchangeRoutes, healthRoutes, queueRoutes } from './routes';
|
import { exchangeRoutes, healthRoutes, queueRoutes } from './routes';
|
||||||
|
|
||||||
// Initialize configuration with automatic monorepo config inheritance
|
const config = initializeConfigSync();
|
||||||
const config = await initializeServiceConfig();
|
|
||||||
const serviceConfig = config.service;
|
const serviceConfig = config.service;
|
||||||
const databaseConfig = config.database;
|
const databaseConfig = config.database;
|
||||||
const queueConfig = config.queue;
|
const queueConfig = config.queue;
|
||||||
|
|
||||||
// Initialize logger with config
|
if (config.log) {
|
||||||
const logConfig = config.log;
|
|
||||||
if (logConfig) {
|
|
||||||
setLoggerConfig({
|
setLoggerConfig({
|
||||||
logLevel: logConfig.level,
|
logLevel: config.log.level,
|
||||||
logConsole: true,
|
logConsole: true,
|
||||||
logFile: false,
|
logFile: false,
|
||||||
environment: config.environment,
|
environment: config.environment,
|
||||||
|
|
@ -101,9 +94,21 @@ async function initializeServices() {
|
||||||
// Initialize queue system
|
// Initialize queue system
|
||||||
logger.debug('Initializing queue system...');
|
logger.debug('Initializing queue system...');
|
||||||
const queueManagerConfig: QueueManagerConfig = {
|
const queueManagerConfig: QueueManagerConfig = {
|
||||||
redis: queueConfig.redis,
|
redis: queueConfig?.redis || {
|
||||||
|
host: 'localhost',
|
||||||
|
port: 6379,
|
||||||
|
db: 1,
|
||||||
|
},
|
||||||
defaultQueueOptions: {
|
defaultQueueOptions: {
|
||||||
defaultJobOptions: queueConfig.defaultJobOptions,
|
defaultJobOptions: queueConfig?.defaultJobOptions || {
|
||||||
|
attempts: 3,
|
||||||
|
backoff: {
|
||||||
|
type: 'exponential',
|
||||||
|
delay: 1000,
|
||||||
|
},
|
||||||
|
removeOnComplete: true,
|
||||||
|
removeOnFail: false,
|
||||||
|
},
|
||||||
workers: 5,
|
workers: 5,
|
||||||
concurrency: 20,
|
concurrency: 20,
|
||||||
enableMetrics: true,
|
enableMetrics: true,
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,51 @@ export class ConfigManager<T = Record<string, unknown>> {
|
||||||
return this.config;
|
return this.config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the configuration synchronously (only env vars, no file loading)
|
||||||
|
*/
|
||||||
|
initializeSync(schema?: ConfigSchema): T {
|
||||||
|
if (this.config) {
|
||||||
|
return this.config;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.schema = schema;
|
||||||
|
|
||||||
|
// Only use EnvLoader for sync initialization
|
||||||
|
const envLoader = this.loaders.find(loader => loader.constructor.name === 'EnvLoader');
|
||||||
|
if (!envLoader) {
|
||||||
|
throw new ConfigError('No EnvLoader found for synchronous initialization');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load env vars synchronously
|
||||||
|
const envLoaderInstance = envLoader as any;
|
||||||
|
const config = envLoaderInstance.loadSync ? envLoaderInstance.loadSync() : {};
|
||||||
|
|
||||||
|
// Add environment if not present
|
||||||
|
if (typeof config === 'object' && config !== null && !('environment' in config)) {
|
||||||
|
(config as Record<string, unknown>)['environment'] = this.environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate if schema provided
|
||||||
|
if (this.schema) {
|
||||||
|
try {
|
||||||
|
this.config = this.schema.parse(config) as T;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof z.ZodError) {
|
||||||
|
throw new ConfigValidationError(
|
||||||
|
'Configuration validation failed',
|
||||||
|
error.errors
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.config = config as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.config;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current configuration
|
* Get the current configuration
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,62 @@ import { EnvLoader } from './loaders/env.loader';
|
||||||
// Create singleton instance
|
// Create singleton instance
|
||||||
let configInstance: ConfigManager<AppConfig> | null = null;
|
let configInstance: ConfigManager<AppConfig> | null = null;
|
||||||
|
|
||||||
|
// Synchronously load critical env vars for early initialization
|
||||||
|
function loadCriticalEnvVarsSync(): void {
|
||||||
|
// Load .env file synchronously if it exists
|
||||||
|
try {
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const envPath = path.resolve(process.cwd(), '.env');
|
||||||
|
if (fs.existsSync(envPath)) {
|
||||||
|
const envContent = fs.readFileSync(envPath, 'utf-8');
|
||||||
|
const lines = envContent.split('\n');
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
if (!trimmed || trimmed.startsWith('#')) continue;
|
||||||
|
|
||||||
|
const equalIndex = trimmed.indexOf('=');
|
||||||
|
if (equalIndex === -1) continue;
|
||||||
|
|
||||||
|
const key = trimmed.substring(0, equalIndex).trim();
|
||||||
|
let value = trimmed.substring(equalIndex + 1).trim();
|
||||||
|
|
||||||
|
// Remove surrounding quotes
|
||||||
|
if ((value.startsWith('"') && value.endsWith('"')) ||
|
||||||
|
(value.startsWith("'") && value.endsWith("'"))) {
|
||||||
|
value = value.slice(1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only set if not already set
|
||||||
|
if (!(key in process.env)) {
|
||||||
|
process.env[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore errors - env file is optional
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load critical env vars immediately
|
||||||
|
loadCriticalEnvVarsSync();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize configuration synchronously (env vars only)
|
||||||
|
* This should be called at the very start of the application
|
||||||
|
*/
|
||||||
|
export function initializeConfigSync(): AppConfig {
|
||||||
|
if (!configInstance) {
|
||||||
|
configInstance = new ConfigManager<AppConfig>({
|
||||||
|
loaders: [
|
||||||
|
new EnvLoader(''), // Environment variables only for sync
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return configInstance.initializeSync(appConfigSchema);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the global configuration
|
* Initialize the global configuration
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ export class EnvLoader implements ConfigLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
async load(): Promise<Record<string, unknown>> {
|
async load(): Promise<Record<string, unknown>> {
|
||||||
|
return this.loadSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadSync(): Record<string, unknown> {
|
||||||
try {
|
try {
|
||||||
// Load root .env file - try multiple possible locations
|
// Load root .env file - try multiple possible locations
|
||||||
const possiblePaths = ['./.env', '../.env', '../../.env'];
|
const possiblePaths = ['./.env', '../.env', '../../.env'];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue