diff --git a/CONNECTION-POOL-IMPLEMENTATION.md b/CONNECTION-POOL-IMPLEMENTATION.md deleted file mode 100644 index 2535b48..0000000 --- a/CONNECTION-POOL-IMPLEMENTATION.md +++ /dev/null @@ -1,145 +0,0 @@ -# Connection Pool Implementation Summary - -## What We've Implemented - -### 1. Removed Singleton Pattern ✅ -- Deleted `libs/mongodb-client/src/singleton.ts` -- Deleted `libs/postgres-client/src/singleton.ts` -- Removed singleton exports from both index files -- Forces all new code to use the connection factory pattern - -### 2. Added Connection Pool Monitoring ✅ -Both MongoDB and PostgreSQL clients now support: -- `getPoolMetrics()` method returning: - - totalConnections - - activeConnections - - idleConnections - - waitingRequests - - errors count - - lastError message - - avgResponseTime - - created timestamp - - lastUsed timestamp - -### 3. Implemented Connection Lifecycle Events ✅ -Both clients now support event callbacks: -```typescript -interface ConnectionEvents { - onConnect?: () => void | Promise; - onDisconnect?: () => void | Promise; - onError?: (error: Error) => void | Promise; - onPoolCreated?: () => void | Promise; -} -``` - -### 4. Dynamic Pool Sizing ✅ -New feature for automatically adjusting pool size based on load: -```typescript -interface DynamicPoolConfig { - enabled: boolean; - minSize: number; - maxSize: number; - scaleUpThreshold: number; // % utilization to trigger scale up - scaleDownThreshold: number; // % utilization to trigger scale down - scaleUpIncrement: number; // connections to add - scaleDownIncrement: number; // connections to remove - evaluationInterval: number; // ms between evaluations -} -``` - -### 5. Pool Warmup Strategy ✅ -- `warmupPool()` method pre-creates minimum connections -- Runs parallel queries/pings to establish connections -- Reduces cold start latency -- Validates connections before marking pool as ready - -## Enhanced Components - -### Connection Factory (`@stock-bot/connection-factory`) -- Manages connection pools across services -- Provides consistent configuration -- Handles lifecycle events -- Supports pool metrics collection - -### Enhanced OperationContext -- Backward compatible with singleton pattern -- Supports dependency injection via ServiceContainer -- Lazy loads database connections -- Proper resource disposal with `dispose()` method - -### Service Container -- Lightweight dependency injection -- Scoped containers for request isolation -- Automatic resource cleanup -- Service lifecycle management - -## Usage Examples - -### Basic Setup -```typescript -// Setup service container with connection pools -const container = await setupServiceContainer(); - -// Create operation context with container -const context = OperationContext.create('handler', 'operation', { - container -}); - -// Use databases normally -await context.mongodb.insertOne(data); -await context.postgres.query('SELECT...'); - -// Clean up when done -await context.dispose(); -``` - -### Dynamic Pool Configuration -```typescript -const dynamicConfig: DynamicPoolConfig = { - enabled: true, - minSize: 5, - maxSize: 100, - scaleUpThreshold: 70, - scaleDownThreshold: 30, - scaleUpIncrement: 10, - scaleDownIncrement: 5, - evaluationInterval: 10000 -}; - -client.setDynamicPoolConfig(dynamicConfig); -``` - -### Monitoring Pool Health -```typescript -// Get current metrics -const metrics = client.getPoolMetrics(); -console.log({ - active: metrics.activeConnections, - total: metrics.totalConnections, - waiting: metrics.waitingRequests -}); - -// Listen to events -const events: ConnectionEvents = { - onError: (error) => logger.error('Pool error', { error }), - onConnect: () => logger.info('Connected') -}; -``` - -## Next Steps - -1. **Migrate Services**: Update each service to use the new pattern -2. **Add Monitoring**: Set up dashboards for pool metrics -3. **Configure Alerts**: Alert on pool exhaustion or high wait times -4. **Performance Testing**: Validate dynamic sizing under load -5. **Documentation**: Update service documentation with pool sizing guidelines - -## Benefits Achieved - -- ✅ No more global state -- ✅ Per-service connection pool optimization -- ✅ Automatic scaling based on load -- ✅ Better resource utilization -- ✅ Improved observability -- ✅ Graceful degradation under load -- ✅ Proper cleanup and lifecycle management \ No newline at end of file diff --git a/DATA-INGESTION-REFACTOR-SUMMARY.md b/DATA-INGESTION-REFACTOR-SUMMARY.md deleted file mode 100644 index cad938a..0000000 --- a/DATA-INGESTION-REFACTOR-SUMMARY.md +++ /dev/null @@ -1,97 +0,0 @@ -# Data-Ingestion Service Refactor Summary - -## What Was Done - -Successfully refactored the `data-ingestion` service to use the new connection pool pattern, completely removing dependencies on the singleton anti-pattern. - -### Key Changes - -1. **Service Container Setup** - - Created `database-setup.ts` with proper connection factory configuration - - Configured appropriate pool sizes for data ingestion workloads - - Added optional dynamic pool sizing for production environments - -2. **Main Service Refactor** (`index.ts`) - - Removed `connectMongoDB()` and `connectPostgreSQL()` singleton calls - - Replaced with `setupServiceContainer()` initialization - - Updated shutdown handlers to dispose container properly - - Routes now have access to the service container - -3. **Handler Updates** - - All handlers now accept `ServiceContainer` parameter - - QM handler operations use container-based OperationContext - - IB, Proxy, and WebShare handlers updated to accept container - - Added proper resource disposal with `ctx.dispose()` - -4. **Route Refactoring** - - Created `create-routes.ts` factory function - - Routes can access container through Hono context - - Maintains backward compatibility for simple routes - -5. **Migration Helper** - - Created temporary migration helper for legacy operations - - Provides `getMongoDBClient()` for IB operations still being migrated - - Includes cleanup in shutdown sequence - -### Configuration Changes - -- Added `@stock-bot/connection-factory` dependency -- Updated `tsconfig.json` with proper references -- Pool sizes optimized for data ingestion: - - MongoDB: 50 connections (batch imports) - - PostgreSQL: 30 connections - - Cache: 20 connections - -### Benefits Achieved - -1. **No More Global State**: Each service manages its own connections -2. **Better Resource Management**: Proper cleanup on shutdown -3. **Scalability**: Dynamic pool sizing for production workloads -4. **Monitoring**: Pool metrics available for observability -5. **Testing**: Easier to test with mock containers -6. **Gradual Migration**: Legacy operations still work during transition - -### Next Steps - -1. **Complete Operation Migration**: Update IB operations to use container -2. **Remove Migration Helper**: Once all operations are migrated -3. **Add Monitoring**: Set up dashboards for pool metrics -4. **Performance Testing**: Validate pool sizes under load -5. **Replicate Pattern**: Apply same refactor to other services - -### Example Usage - -```typescript -// Handler with container -export function initializeHandler(container: ServiceContainer) { - const config = { - operations: { - 'my-operation': createJobHandler(async (payload) => { - // Operation uses container - const ctx = OperationContext.create('handler', 'operation', { container }); - try { - // Use databases through context - await ctx.mongodb.insertOne(data); - await ctx.postgres.query('...'); - return { success: true }; - } finally { - await ctx.dispose(); // Clean up resources - } - }) - } - }; -} -``` - -### Migration Checklist - -- [x] Remove singleton imports from index.ts -- [x] Create service container setup -- [x] Update all handlers to accept container -- [x] Create route factory with container access -- [x] Add migration helper for legacy code -- [x] Update shutdown handlers -- [x] Test build successfully -- [ ] Migrate remaining operations -- [ ] Remove migration helper -- [ ] Deploy and monitor \ No newline at end of file diff --git a/DI-CONTAINER-SIMPLIFICATION.md b/DI-CONTAINER-SIMPLIFICATION.md deleted file mode 100644 index 1cd2ddb..0000000 --- a/DI-CONTAINER-SIMPLIFICATION.md +++ /dev/null @@ -1,142 +0,0 @@ -# DI Container Configuration Simplification - -## Overview - -We've simplified the dependency injection container setup across all backend services by creating a new `createServiceContainerFromConfig` function that directly accepts the AppConfig, eliminating repetitive configuration mapping code. - -## Before vs After - -### Before (30+ lines per service) -```typescript -// In each service's index.ts -const awilixConfig = { - redis: { - host: config.database.dragonfly.host, - port: config.database.dragonfly.port, - db: config.database.dragonfly.db, - }, - mongodb: { - uri: config.database.mongodb.uri, - database: config.database.mongodb.database, - }, - postgres: { - host: config.database.postgres.host, - port: config.database.postgres.port, - database: config.database.postgres.database, - user: config.database.postgres.user, - password: config.database.postgres.password, - }, - questdb: { - enabled: false, - host: config.database.questdb.host, - httpPort: config.database.questdb.httpPort, - pgPort: config.database.questdb.pgPort, - influxPort: config.database.questdb.ilpPort, - database: config.database.questdb.database, - }, -}; - -container = createServiceContainer(awilixConfig); -``` - -### After (2-3 lines per service) -```typescript -// In each service's index.ts -container = createServiceContainerFromConfig(config, { - enableQuestDB: false, // Service-specific options - enableMongoDB: true, - enablePostgres: true, - // ... other options -}); -``` - -## Benefits - -1. **Code Reduction**: ~30 lines reduced to 2-3 lines per service -2. **Centralized Mapping**: Configuration structure mapping is now in one place -3. **Service-Specific Control**: Each service can enable/disable specific components -4. **Type Safety**: Direct use of AppConfig ensures type safety -5. **Maintainability**: Changes to config structure only need updates in one place - -## Service Configurations - -### Data Ingestion Service -```typescript -container = createServiceContainerFromConfig(config, { - enableQuestDB: false, // Not needed yet - enableMongoDB: true, // Stores raw data - enablePostgres: true, // Stores metadata - enableCache: true, // For rate limiting - enableQueue: true, // Job processing - enableBrowser: true, // Web scraping - enableProxy: true, // Proxy rotation -}); -``` - -### Data Pipeline Service -```typescript -container = createServiceContainerFromConfig(config, { - enableQuestDB: config.database.questdb?.enabled || false, - enableMongoDB: true, // Reads raw data - enablePostgres: true, // Writes processed data - enableCache: true, // Query caching - enableQueue: true, // Job processing - enableBrowser: false, // Not needed - enableProxy: false, // Not needed -}); -``` - -### Web API Service -```typescript -container = createServiceContainerFromConfig(config, { - enableQuestDB: false, // Not needed - enableMongoDB: true, // Reads data - enablePostgres: true, // Reads data - enableCache: true, // API caching - enableQueue: false, // No job processing - enableBrowser: false, // Not needed - enableProxy: false, // Not needed -}); -``` - -## Implementation Details - -The new function in `@stock-bot/di/awilix-container.ts`: -- Accepts the standard AppConfig from `@stock-bot/config` -- Maps the nested config structure to what Awilix expects -- Provides sensible defaults for all options -- Only creates services that are enabled for the specific service - -## Migration Guide - -To migrate a service: - -1. Change the import: - ```typescript - // Before - import { createServiceContainer, ... } from '@stock-bot/di'; - - // After - import { createServiceContainerFromConfig, ... } from '@stock-bot/di'; - ``` - -2. Replace the config mapping: - ```typescript - // Before - const awilixConfig = { /* 30+ lines of mapping */ }; - container = createServiceContainer(awilixConfig); - - // After - container = createServiceContainerFromConfig(config, { - // Service-specific options - }); - ``` - -3. Choose which services to enable based on your service's needs - -## Result - -- **3 services updated**: data-ingestion, data-pipeline, web-api -- **~90 lines of code removed** (30 lines × 3 services) -- **Cleaner, more maintainable codebase** -- **Easier to add new services** with minimal boilerplate \ No newline at end of file diff --git a/MIGRATION-CLEANUP-SUMMARY.md b/MIGRATION-CLEANUP-SUMMARY.md deleted file mode 100644 index 74b5bf0..0000000 --- a/MIGRATION-CLEANUP-SUMMARY.md +++ /dev/null @@ -1,120 +0,0 @@ -# Migration Helper Cleanup Summary - -## Overview - -Successfully removed all migration helpers and completed the transition to dependency injection (DI) container pattern across all backend services. This cleanup eliminates temporary migration code that was used during the refactoring process. - -## Removed Files - -### Migration Helper Files -- `/apps/data-pipeline/src/migration-helper.ts` ❌ DELETED -- `/apps/web-api/src/migration-helper.ts` ❌ DELETED - -### Singleton Client Files -- `/apps/data-pipeline/src/clients.ts` ❌ DELETED -- `/apps/web-api/src/clients.ts` ❌ DELETED - -## Code Changes - -### Service Index Files -**Data Pipeline** (`apps/data-pipeline/src/index.ts`) -- ❌ Removed migration helper import and initialization -- ✅ Now uses pure DI container pattern - -**Web API** (`apps/web-api/src/index.ts`) -- ❌ Removed migration helper import and initialization -- ✅ Now uses pure DI container pattern - -### Operations Files Migration -**Fixed remaining operations that weren't properly migrated:** - -1. **sync-symbols-from-provider.operations.ts** - Complete migration - - ✅ Added container parameter to main function - - ✅ Updated all helper functions to accept container parameter - - ✅ Removed all `getPostgreSQLClient()` and `getMongoDBClient()` usage - - ✅ Now uses `container.postgres` and `container.mongodb` - -2. **sync-status.operations.ts** - Complete migration - - ✅ Added container parameter - - ✅ Updated to use `container.postgres` - -3. **qm-symbols.operations.ts** - Complete migration - - ✅ Added container parameter - - ✅ Updated to use `container.postgres` and `container.mongodb` - -### Route Files Migration -**Health Routes** (`apps/web-api/src/routes/health.routes.ts`) -- ✅ Converted from static export to factory function pattern -- ✅ Added `createHealthRoutes(container)` function -- ✅ Updated database checks to use `container.postgres` and `container.mongodb` -- ✅ Updated route creation in `create-routes.ts` to use factory function - -### Import Cleanup -**Removed obsolete imports from all operations files:** -- ❌ `import { getMongoDBClient, getPostgreSQLClient } from '../../../clients'` -- ✅ Only imports `import type { IServiceContainer } from '@stock-bot/handlers'` - -## Verification - -### Build Success -- ✅ All libraries build successfully (`bun run build:libs`) -- ✅ All applications build successfully (`bun run build`) -- ✅ No TypeScript errors related to missing dependencies -- ✅ No references to singleton getters remaining in codebase - -### Code Search Verification -```bash -# Verified no remaining references to: -grep -r "getMongoDBClient\|getPostgreSQLClient\|getQuestDBClient" apps/ -# Result: No files found ✅ -``` - -## Benefits Achieved - -1. **Cleaner Codebase**: Removed ~300 lines of temporary migration code -2. **Consistent Pattern**: All services now use pure DI container pattern -3. **Type Safety**: Proper TypeScript interfaces throughout -4. **Maintainability**: No more dual patterns or migration helpers -5. **Testability**: All dependencies properly injected for easy mocking - -## Current Service Architecture - -All backend services now follow the same clean DI pattern: - -```typescript -// Service initialization -container = createServiceContainerFromConfig(config, options); -await initializeAwilixServices(container); -const serviceContainer = container.resolve('serviceContainer'); - -// Route creation -const routes = createRoutes(serviceContainer); - -// Operation functions -export async function operation( - payload: JobPayload, - container: IServiceContainer -): Promise { - const db = container.mongodb; - const postgres = container.postgres; - // ... implementation -} -``` - -## Next Steps - -The DI container migration is now **complete**. The codebase is ready for: - -1. ✅ Production deployment without migration helpers -2. ✅ Connection pool monitoring and metrics implementation -3. ✅ Enhanced error handling and circuit breakers -4. ✅ Data validation and quality metrics - -## Migration Timeline - -- **Phase 1**: ✅ IB handler migration (previous session) -- **Phase 2**: ✅ DI container pattern for data-pipeline and web-api (previous session) -- **Phase 3**: ✅ DI container configuration simplification (previous session) -- **Phase 4**: ✅ Migration helper cleanup (this session) - -**Total Migration**: **COMPLETED** 🎉 \ No newline at end of file diff --git a/SERVICE-APPLICATION-REFACTOR.md b/SERVICE-APPLICATION-REFACTOR.md deleted file mode 100644 index 1382c47..0000000 --- a/SERVICE-APPLICATION-REFACTOR.md +++ /dev/null @@ -1,185 +0,0 @@ -# Service Application Refactoring Summary - -## Overview - -Successfully refactored all backend services to use a new `ServiceApplication` framework that encapsulates common service initialization patterns, dramatically reducing code duplication and improving maintainability. - -## What Was Achieved - -### 1. **ServiceApplication Framework** (`libs/core/di/src/service-application.ts`) -Created a comprehensive service lifecycle management class that handles: -- ✅ Logger configuration setup -- ✅ Hono app creation with CORS middleware -- ✅ HTTP server management -- ✅ Graceful shutdown handler registration -- ✅ Scheduled job initialization -- ✅ Container lifecycle management -- ✅ Service metadata endpoints - -### 2. **Index File Simplification** -Reduced index.ts files from ~250 lines to ~80 lines each: - -| Service | Before | After | Reduction | -|---------|--------|-------|-----------| -| data-ingestion | 257 lines | 73 lines | **71%** | -| data-pipeline | 248 lines | 80 lines | **68%** | -| web-api | 183 lines | 78 lines | **57%** | - -### 3. **Common Patterns Extracted** -Moved repetitive code to ServiceApplication: -- Logger configuration (20 lines per service) -- CORS setup (10 lines per service) -- Shutdown handlers (60 lines per service) -- Scheduled job creation (45 lines per service) -- Server startup logic (20 lines per service) - -## Code Comparison - -### Before (data-ingestion/index.ts) -```typescript -// 250+ lines of boilerplate including: -- Manual logger configuration -- Container creation and initialization -- Hono app setup with CORS -- Handler initialization -- Scheduled job creation logic -- Multiple shutdown handlers -- Server startup logic -- Error handling -``` - -### After (data-ingestion/index.ts) -```typescript -// 73 clean lines focused on service-specific configuration: -const app = new ServiceApplication( - config, - { - serviceName: 'data-ingestion', - enableHandlers: true, - enableScheduledJobs: true, - corsConfig: { /* service-specific */ }, - serviceMetadata: { /* service info */ } - } -); - -// Simple container factory -async function createContainer(config: any) { - const container = createServiceContainerFromConfig(config, { - // Service-specific options - }); - await initializeAwilixServices(container); - return container; -} - -// One-line startup -app.start(createContainer, createRoutes, initializeAllHandlers); -``` - -## Benefits Achieved - -### 1. **Code Reduction** -- Removed ~300 lines of duplicated boilerplate across services -- Each service now focuses only on its unique configuration - -### 2. **Consistency** -- All services follow identical initialization patterns -- Standardized error handling and logging -- Uniform shutdown behavior - -### 3. **Maintainability** -- Changes to startup logic only need to be made in one place -- New services can be created with minimal boilerplate -- Clear separation between framework and service logic - -### 4. **Extensibility** -- Lifecycle hooks for service customization -- Service-specific configuration options -- Easy to add new common patterns - -### 5. **Type Safety** -- Strongly typed configuration interfaces -- TypeScript inference for CORS options -- Proper container typing throughout - -## Service Configurations - -### Data Ingestion Service -- **Handlers**: ✅ Enabled (for data provider handlers) -- **Scheduled Jobs**: ✅ Enabled (for periodic data fetching) -- **CORS**: Permissive (for development) -- **Databases**: MongoDB, PostgreSQL, Cache -- **Special**: Browser & Proxy for web scraping - -### Data Pipeline Service -- **Handlers**: ✅ Enabled (for data processing operations) -- **Scheduled Jobs**: ✅ Enabled (for batch processing) -- **CORS**: Permissive -- **Databases**: All (MongoDB, PostgreSQL, QuestDB optional) -- **Special**: Container setup for enhanced features - -### Web API Service -- **Handlers**: ❌ Disabled (REST API only) -- **Scheduled Jobs**: ❌ Disabled (no background jobs) -- **CORS**: Restricted to frontend origins -- **Databases**: MongoDB, PostgreSQL, Cache -- **Special**: Credentials enabled for frontend - -## Architecture Improvements - -1. **Separation of Concerns** - - ServiceApplication handles infrastructure - - Index files handle service-specific logic - - Clear boundaries between framework and application - -2. **Lifecycle Management** - - Structured initialization phases - - Proper resource cleanup - - Graceful shutdown coordination - -3. **Error Handling** - - Centralized error logging - - Consistent error reporting - - Proper cleanup on failures - -## Future Enhancements - -While not implemented in this phase, the framework is ready for: - -1. **Health Check Endpoints** - - Standardized health checks - - Readiness/liveness probes - - Dependency health monitoring - -2. **Metrics Collection** - - Request/response metrics - - Performance monitoring - - Resource usage tracking - -3. **Service Discovery** - - Registration with service registry - - Dynamic configuration updates - - Inter-service communication - -4. **Enhanced Middleware** - - Authentication/authorization - - Request validation - - Response compression - -## Migration Impact - -- **Zero Breaking Changes**: All services maintain their existing APIs -- **Backward Compatible**: No changes to routes, handlers, or operations -- **Drop-in Replacement**: Services can be migrated one at a time -- **Tested**: All services build and pass type checking - -## Conclusion - -The ServiceApplication framework successfully abstracts common microservice patterns while maintaining flexibility for service-specific needs. This refactoring has: - -- ✅ Reduced code duplication by 65% -- ✅ Improved consistency across services -- ✅ Enhanced maintainability -- ✅ Preserved all existing functionality -- ✅ Created a foundation for future enhancements - -The codebase is now cleaner, more maintainable, and ready for the next phase of development. \ No newline at end of file diff --git a/docs/batch-processing-migration.md b/docs/batch-processing-migration.md deleted file mode 100644 index e987ffd..0000000 --- a/docs/batch-processing-migration.md +++ /dev/null @@ -1,176 +0,0 @@ -# Batch Processing Migration Guide - -## ✅ MIGRATION COMPLETED - -The migration from the complex `BatchProcessor` class to the new functional batch processing approach has been **successfully completed**. The old `BatchProcessor` class has been removed entirely. - -## Overview - -The new functional batch processing approach simplified the complex `BatchProcessor` class into simple, composable functions. - -## Key Benefits Achieved - -✅ **90% less code** - From 545 lines to ~200 lines -✅ **Simpler API** - Just function calls instead of class instantiation -✅ **Better performance** - Less overhead and memory usage -✅ **Same functionality** - All features preserved -✅ **Type safe** - Better TypeScript support -✅ **No more payload conflicts** - Single consistent batch system - -## Available Functions - -All batch processing now uses the new functional approach: - -### 1. `processItems()` - Generic processing - -```typescript -import { processItems } from '../utils/batch-helpers'; - -const result = await processItems( - items, - (item, index) => ({ /* transform item */ }), - queueManager, - { - totalDelayMs: 60000, - useBatching: false, - batchSize: 100, - priority: 1 - } -); -``` - -### 2. `processSymbols()` - Stock symbol processing - -```typescript -import { processSymbols } from '../utils/batch-helpers'; - -const result = await processSymbols(['AAPL', 'GOOGL'], queueManager, { - operation: 'live-data', - service: 'market-data', - provider: 'yahoo', - totalDelayMs: 300000, - useBatching: false, - priority: 1, - service: 'market-data', - provider: 'yahoo', - operation: 'live-data' -}); -``` - -### 3. `processBatchJob()` - Worker batch handler - -```typescript -import { processBatchJob } from '../utils/batch-helpers'; - -// In your worker job handler -const result = await processBatchJob(jobData, queueManager); -``` - -## Configuration Mapping - -| Old BatchConfig | New ProcessOptions | Description | -|----------------|-------------------|-------------| -| `items` | First parameter | Items to process | -| `createJobData` | Second parameter | Transform function | -| `queueManager` | Third parameter | Queue instance | -| `totalDelayMs` | `totalDelayMs` | Total processing time | -| `batchSize` | `batchSize` | Items per batch | -| `useBatching` | `useBatching` | Batch vs direct mode | -| `priority` | `priority` | Job priority | -| `removeOnComplete` | `removeOnComplete` | Job cleanup | -| `removeOnFail` | `removeOnFail` | Failed job cleanup | -| `payloadTtlHours` | `ttl` | Cache TTL in seconds | - -## Return Value Changes - -### Before -```typescript -{ - totalItems: number, - jobsCreated: number, - mode: 'direct' | 'batch', - optimized?: boolean, - batchJobsCreated?: number, - // ... other complex fields -} -``` - -### After -```typescript -{ - jobsCreated: number, - mode: 'direct' | 'batch', - totalItems: number, - batchesCreated?: number, - duration: number -} -``` - -## Provider Migration - -### ✅ Current Implementation - -All providers now use the new functional approach: - -```typescript -'process-batch-items': async (payload: any) => { - const { processBatchJob } = await import('../utils/batch-helpers'); - return await processBatchJob(payload, queueManager); -} -``` - -## Testing the New Approach - -Use the new test endpoints: - -```bash -# Test symbol processing -curl -X POST http://localhost:3002/api/test/batch-symbols \ - -H "Content-Type: application/json" \ - -d '{"symbols": ["AAPL", "GOOGL"], "useBatching": false, "totalDelayMs": 10000}' - -# Test custom processing -curl -X POST http://localhost:3002/api/test/batch-custom \ - -H "Content-Type: application/json" \ - -d '{"items": [1,2,3,4,5], "useBatching": true, "totalDelayMs": 15000}' -``` - -## Performance Improvements - -| Metric | Before | After | Improvement | -|--------|--------|-------|-------------| -| Code Lines | 545 | ~200 | 63% reduction | -| Memory Usage | High | Low | ~40% less | -| Initialization Time | ~2-10s | Instant | 100% faster | -| API Complexity | High | Low | Much simpler | -| Type Safety | Medium | High | Better types | - -## ✅ Migration Complete - -The old `BatchProcessor` class has been completely removed. All batch processing now uses the simplified functional approach. - -## Common Issues & Solutions - -### Function Serialization -The new approach serializes processor functions for batch jobs. Avoid: -- Closures with external variables -- Complex function dependencies -- Non-serializable objects - -**Good:** -```typescript -(item, index) => ({ id: item.id, index }) -``` - -**Bad:** -```typescript -const externalVar = 'test'; -(item, index) => ({ id: item.id, external: externalVar }) // Won't work -``` - -### Cache Dependencies -The functional approach automatically handles cache initialization. No need to manually wait for cache readiness. - -## Need Help? - -Check the examples in `apps/data-ingestion/src/examples/batch-processing-examples.ts` for more detailed usage patterns. diff --git a/libs/core/di/src/awilix-container.ts b/libs/core/di/src/awilix-container.ts index 565cd06..dcef384 100644 --- a/libs/core/di/src/awilix-container.ts +++ b/libs/core/di/src/awilix-container.ts @@ -3,10 +3,9 @@ * Creates a decoupled, reusable dependency injection container */ -import { asFunction, asValue, createContainer, InjectionMode, type AwilixContainer } from 'awilix'; -import { z } from 'zod'; import { Browser } from '@stock-bot/browser'; import { createCache, type CacheProvider } from '@stock-bot/cache'; +import type { AppConfig as StockBotAppConfig } from '@stock-bot/config'; import type { IServiceContainer } from '@stock-bot/handlers'; import { getLogger, type Logger } from '@stock-bot/logger'; import { MongoDBClient } from '@stock-bot/mongodb'; @@ -14,7 +13,8 @@ import { PostgreSQLClient } from '@stock-bot/postgres'; import { ProxyManager } from '@stock-bot/proxy'; import { QuestDBClient } from '@stock-bot/questdb'; import { type QueueManager } from '@stock-bot/queue'; -import type { AppConfig as StockBotAppConfig } from '@stock-bot/config'; +import { asFunction, asValue, createContainer, InjectionMode, type AwilixContainer } from 'awilix'; +import { z } from 'zod'; // Configuration schema with validation const appConfigSchema = z.object({ diff --git a/libs/core/di/tsconfig.json b/libs/core/di/tsconfig.json index 0177a72..23f0683 100644 --- a/libs/core/di/tsconfig.json +++ b/libs/core/di/tsconfig.json @@ -10,5 +10,5 @@ }, "include": ["src/**/*.ts"], "exclude": ["node_modules", "dist", "test"], - "references": [{ "path": "../config" }, { "path": "../logger" }] + "references": [{ "path": "../config" }, { "path": "../logger" }, { "path": "../../services/queue" }] }