removing deprecations

This commit is contained in:
Boki 2025-06-24 15:32:56 -04:00
parent fa67d666dc
commit f6038d385f
21 changed files with 91 additions and 158 deletions

View file

@ -1,4 +1,3 @@
import { getRandomUserAgent } from '@stock-bot/utils'; import { getRandomUserAgent } from '@stock-bot/utils';
import type { CeoHandler } from '../ceo.handler'; import type { CeoHandler } from '../ceo.handler';
@ -40,7 +39,7 @@ export async function processIndividualSymbol(
} }
this.logger.info( this.logger.info(
`Successfully processed CEO symbol ${symbol} shorts and found ${shortCount} positions`, `Successfully processed CEO symbol ${symbol} shorts and found ${shortCount} positions`
); );
return { ceoId, shortCount, timestamp }; return { ceoId, shortCount, timestamp };

View file

@ -39,7 +39,11 @@ export async function processIndividualSymbol(
const spielCount = data.spiels.length; const spielCount = data.spiels.length;
if (spielCount === 0) { if (spielCount === 0) {
this.logger.warn(`No spiels found for ceoId ${ceoId}`); this.logger.warn(`No spiels found for ceoId ${ceoId}`);
await this.mongodb.updateMany('ceoChannels', { ceoId }, { $set: { lastSpielTime: timestamp, finished: true } }); await this.mongodb.updateMany(
'ceoChannels',
{ ceoId },
{ $set: { lastSpielTime: timestamp, finished: true } }
);
return null; // No data to process return null; // No data to process
} }
const latestSpielTime = data.spiels[0]?.timestamp; const latestSpielTime = data.spiels[0]?.timestamp;
@ -77,7 +81,11 @@ export async function processIndividualSymbol(
})); }));
await this.mongodb.batchUpsert('ceoPosts', posts, ['spielId']); await this.mongodb.batchUpsert('ceoPosts', posts, ['spielId']);
await this.mongodb.updateMany('ceoChannels', { ceoId }, { $set: { lastSpielTime: latestSpielTime } }); await this.mongodb.updateMany(
'ceoChannels',
{ ceoId },
{ $set: { lastSpielTime: latestSpielTime } }
);
this.logger.info(`Fetched ${spielCount} spiels for ceoId ${ceoId}`); this.logger.info(`Fetched ${spielCount} spiels for ceoId ${ceoId}`);
await this.scheduleOperation( await this.scheduleOperation(

View file

@ -32,7 +32,7 @@ export async function initializeAllHandlers(serviceContainer: IServiceContainer)
count: handlers.length, count: handlers.length,
handlers: handlers.map(h => (h as any).__handlerName || h.name), handlers: handlers.map(h => (h as any).__handlerName || h.name),
}); });
// Log what metadata the handlers have // Log what metadata the handlers have
for (const HandlerClass of handlers) { for (const HandlerClass of handlers) {
const metadata = (HandlerClass as any).__handlerMetadata; const metadata = (HandlerClass as any).__handlerMetadata;
@ -46,7 +46,7 @@ export async function initializeAllHandlers(serviceContainer: IServiceContainer)
// Get the DI container from the service container // Get the DI container from the service container
const diContainer = (serviceContainer as any)._diContainer; const diContainer = (serviceContainer as any)._diContainer;
if (diContainer?.resolve) { if (diContainer?.resolve) {
// Get handler scanner from DI container // Get handler scanner from DI container
const scanner = diContainer.resolve('handlerScanner'); const scanner = diContainer.resolve('handlerScanner');
@ -58,7 +58,7 @@ export async function initializeAllHandlers(serviceContainer: IServiceContainer)
} else { } else {
logger.warn('Handler scanner not found or missing registerHandlerClass method'); logger.warn('Handler scanner not found or missing registerHandlerClass method');
} }
// Also check the handler registry directly // Also check the handler registry directly
const handlerRegistry = diContainer.resolve('handlerRegistry'); const handlerRegistry = diContainer.resolve('handlerRegistry');
if (handlerRegistry) { if (handlerRegistry) {

View file

@ -1,9 +1,4 @@
import { import { BaseHandler, Handler, Operation, ScheduledOperation } from '@stock-bot/handlers';
BaseHandler,
Handler,
Operation,
ScheduledOperation,
} from '@stock-bot/handlers';
import type { IServiceContainer } from '@stock-bot/types'; import type { IServiceContainer } from '@stock-bot/types';
import { clearPostgreSQLData } from './operations/clear-postgresql-data.operations'; import { clearPostgreSQLData } from './operations/clear-postgresql-data.operations';
import { getSyncStatus } from './operations/enhanced-sync-status.operations'; import { getSyncStatus } from './operations/enhanced-sync-status.operations';

View file

@ -1,5 +1,5 @@
import type { IServiceContainer } from '@stock-bot/types';
import { getLogger } from '@stock-bot/logger'; import { getLogger } from '@stock-bot/logger';
import type { IServiceContainer } from '@stock-bot/types';
import type { JobPayload } from '../../../types/job-payloads'; import type { JobPayload } from '../../../types/job-payloads';
const logger = getLogger('sync-qm-exchanges'); const logger = getLogger('sync-qm-exchanges');

View file

@ -2,8 +2,8 @@
* Exchange management routes - Refactored * Exchange management routes - Refactored
*/ */
import { Hono } from 'hono'; import { Hono } from 'hono';
import type { IServiceContainer } from '@stock-bot/types';
import { getLogger } from '@stock-bot/logger'; import { getLogger } from '@stock-bot/logger';
import type { IServiceContainer } from '@stock-bot/types';
import { createExchangeService } from '../services/exchange.service'; import { createExchangeService } from '../services/exchange.service';
import { createSuccessResponse, handleError } from '../utils/error-handler'; import { createSuccessResponse, handleError } from '../utils/error-handler';
import { import {

View file

@ -1,5 +1,5 @@
import type { IServiceContainer } from '@stock-bot/types';
import { getLogger } from '@stock-bot/logger'; import { getLogger } from '@stock-bot/logger';
import type { IServiceContainer } from '@stock-bot/types';
import { import {
CreateExchangeRequest, CreateExchangeRequest,
CreateProviderMappingRequest, CreateProviderMappingRequest,

View file

@ -818,12 +818,12 @@ export class MonitoringService {
const workers = await bullQueue.getWorkers(); const workers = await bullQueue.getWorkers();
return workers.length; return workers.length;
} }
// Fallback to getWorkersCount if available // Fallback to getWorkersCount if available
if (bullQueue.getWorkersCount && typeof bullQueue.getWorkersCount === 'function') { if (bullQueue.getWorkersCount && typeof bullQueue.getWorkersCount === 'function') {
return await bullQueue.getWorkersCount(); return await bullQueue.getWorkersCount();
} }
return 0; return 0;
} catch (error) { } catch (error) {
this.logger.debug('Failed to get active worker count from BullMQ', { error }); this.logger.debug('Failed to get active worker count from BullMQ', { error });

View file

@ -305,18 +305,18 @@ export class RedisCache implements CacheProvider {
return null; return null;
} }
this.updateStats(true); this.updateStats(true);
try { try {
const parsed = JSON.parse(value); const parsed = JSON.parse(value);
this.logger.debug('Cache raw get hit', { key }); this.logger.debug('Cache raw get hit', { key });
return parsed; return parsed;
} catch (error) { } catch (error) {
// If JSON parsing fails, log the error with more context // If JSON parsing fails, log the error with more context
this.logger.warn('Cache getRaw JSON parse failed', { this.logger.warn('Cache getRaw JSON parse failed', {
key, key,
valueLength: value.length, valueLength: value.length,
valuePreview: value.substring(0, 100), valuePreview: value.substring(0, 100),
error: error instanceof Error ? error.message : String(error) error: error instanceof Error ? error.message : String(error),
}); });
// Return the raw value as-is if it can't be parsed // Return the raw value as-is if it can't be parsed
return value as unknown as T; return value as unknown as T;

View file

@ -4,7 +4,6 @@ import { join } from 'path';
import { parseArgs } from 'util'; import { parseArgs } from 'util';
import { redactSecrets } from './utils/secrets'; import { redactSecrets } from './utils/secrets';
import { import {
checkDeprecations,
checkRequiredEnvVars, checkRequiredEnvVars,
formatValidationResult, formatValidationResult,
validateCompleteness, validateCompleteness,
@ -24,11 +23,6 @@ interface CliOptions {
help?: boolean; help?: boolean;
} }
const DEPRECATIONS = {
'service.legacyMode': 'Use service.mode instead',
'database.redis': 'Use database.dragonfly instead',
};
const REQUIRED_PATHS = [ const REQUIRED_PATHS = [
'service.name', 'service.name',
'service.port', 'service.port',
@ -149,18 +143,6 @@ async function main() {
console.log(formatValidationResult(pathResult)); console.log(formatValidationResult(pathResult));
console.log(); console.log();
// Deprecations
console.log('4. Deprecation Warnings:');
const warnings = checkDeprecations(config, DEPRECATIONS);
if (warnings && warnings.length > 0) {
for (const warning of warnings) {
console.log(` ⚠️ ${warning.path}: ${warning.message}`);
}
} else {
console.log(' ✅ No deprecated options found');
}
console.log();
// Overall result // Overall result
const allValid = schemaResult.valid && envResult.valid && pathResult.valid; const allValid = schemaResult.valid && envResult.valid && pathResult.valid;

View file

@ -37,40 +37,6 @@ export function validateConfig<T>(config: unknown, schema: z.ZodSchema<T>): Vali
} }
} }
/**
* Check for deprecated configuration options
*/
export function checkDeprecations(
config: Record<string, unknown>,
deprecations: Record<string, string>
): ValidationResult['warnings'] {
const warnings: ValidationResult['warnings'] = [];
function checkObject(obj: Record<string, unknown>, path: string[] = []): void {
for (const [key, value] of Object.entries(obj)) {
const currentPath = [...path, key];
const pathStr = currentPath.join('.');
if (pathStr in deprecations) {
const deprecationMessage = deprecations[pathStr];
if (deprecationMessage) {
warnings?.push({
path: pathStr,
message: deprecationMessage,
});
}
}
if (value && typeof value === 'object' && !Array.isArray(value)) {
checkObject(value as Record<string, unknown>, currentPath);
}
}
}
checkObject(config);
return warnings;
}
/** /**
* Check for required environment variables * Check for required environment variables
*/ */

View file

@ -6,7 +6,7 @@ import type { MongoDBClient } from '@stock-bot/mongodb';
import type { PostgreSQLClient } from '@stock-bot/postgres'; import type { PostgreSQLClient } from '@stock-bot/postgres';
import type { ProxyManager } from '@stock-bot/proxy'; import type { ProxyManager } from '@stock-bot/proxy';
import type { QuestDBClient } from '@stock-bot/questdb'; import type { QuestDBClient } from '@stock-bot/questdb';
import type { SmartQueueManager } from '@stock-bot/queue'; import type { QueueManager } from '@stock-bot/queue';
import type { IServiceContainer } from '@stock-bot/types'; import type { IServiceContainer } from '@stock-bot/types';
import type { AppConfig } from '../config/schemas'; import type { AppConfig } from '../config/schemas';
import type { HandlerScanner } from '../scanner'; import type { HandlerScanner } from '../scanner';
@ -25,7 +25,7 @@ export interface ServiceDefinitions {
globalCache: CacheProvider | null; globalCache: CacheProvider | null;
proxyManager: ProxyManager | null; proxyManager: ProxyManager | null;
browser: Browser; browser: Browser;
queueManager: SmartQueueManager | null; queueManager: QueueManager | null;
// Database clients // Database clients
mongoClient: MongoDBClient | null; mongoClient: MongoDBClient | null;

View file

@ -61,7 +61,7 @@ export function registerApplicationServices(
if (config.queue?.enabled && config.redis.enabled) { if (config.queue?.enabled && config.redis.enabled) {
container.register({ container.register({
queueManager: asFunction(({ logger, handlerRegistry }) => { queueManager: asFunction(({ logger, handlerRegistry }) => {
const { SmartQueueManager } = require('@stock-bot/queue'); const { QueueManager } = require('@stock-bot/queue');
const queueConfig = { const queueConfig = {
serviceName: config.service?.serviceName || config.service?.name || 'unknown', serviceName: config.service?.serviceName || config.service?.name || 'unknown',
redis: { redis: {
@ -79,7 +79,7 @@ export function registerApplicationServices(
delayWorkerStart: config.queue!.delayWorkerStart ?? true, // Changed to true so ServiceApplication can start workers delayWorkerStart: config.queue!.delayWorkerStart ?? true, // Changed to true so ServiceApplication can start workers
autoDiscoverHandlers: true, autoDiscoverHandlers: true,
}; };
return new SmartQueueManager(queueConfig, handlerRegistry, logger); return new QueueManager(queueConfig, handlerRegistry, logger);
}).singleton(), }).singleton(),
}); });
} else { } else {

View file

@ -3,7 +3,7 @@
* Discovers and registers handlers with the DI container * Discovers and registers handlers with the DI container
*/ */
import { asClass, asFunction, type AwilixContainer } from 'awilix'; import { asFunction, type AwilixContainer } from 'awilix';
import { glob } from 'glob'; import { glob } from 'glob';
import type { import type {
HandlerConfiguration, HandlerConfiguration,
@ -82,7 +82,7 @@ export class HandlerScanner {
* Check if an exported value is a handler * Check if an exported value is a handler
*/ */
private isHandler(exported: any): boolean { private isHandler(exported: any): boolean {
if (typeof exported !== 'function') return false; if (typeof exported !== 'function') {return false;}
// Check for handler metadata added by decorators // Check for handler metadata added by decorators
const hasHandlerName = !!(exported as any).__handlerName; const hasHandlerName = !!(exported as any).__handlerName;

View file

@ -3,16 +3,16 @@
* Encapsulates common patterns for Hono-based microservices * Encapsulates common patterns for Hono-based microservices
*/ */
import type { AwilixContainer } from 'awilix';
import { Hono } from 'hono'; import { Hono } from 'hono';
import { cors } from 'hono/cors'; import { cors } from 'hono/cors';
import type { BaseAppConfig, UnifiedAppConfig } from '@stock-bot/config'; import type { BaseAppConfig, UnifiedAppConfig } from '@stock-bot/config';
import { toUnifiedConfig } from '@stock-bot/config'; import { toUnifiedConfig } from '@stock-bot/config';
import type { HandlerRegistry } from '@stock-bot/handler-registry';
import { getLogger, setLoggerConfig, shutdownLoggers, type Logger } from '@stock-bot/logger'; import { getLogger, setLoggerConfig, shutdownLoggers, type Logger } from '@stock-bot/logger';
import { Shutdown } from '@stock-bot/shutdown'; import { Shutdown } from '@stock-bot/shutdown';
import type { IServiceContainer } from '@stock-bot/types'; import type { IServiceContainer } from '@stock-bot/types';
import type { HandlerRegistry } from '@stock-bot/handler-registry';
import type { ServiceDefinitions } from './container/types'; import type { ServiceDefinitions } from './container/types';
import type { AwilixContainer } from 'awilix';
/** /**
* Configuration for ServiceApplication * Configuration for ServiceApplication
@ -279,8 +279,8 @@ export class ServiceApplication {
if (this.serviceConfig.enableHandlers && handlerInitializer) { if (this.serviceConfig.enableHandlers && handlerInitializer) {
this.logger.debug('Initializing handlers...'); this.logger.debug('Initializing handlers...');
// Pass the service container with the DI container attached // Pass the service container with the DI container attached
const containerWithDI = Object.assign({}, this.serviceContainer, { const containerWithDI = Object.assign({}, this.serviceContainer, {
_diContainer: this.container _diContainer: this.container,
}); });
await handlerInitializer(containerWithDI); await handlerInitializer(containerWithDI);
this.logger.info('Handlers initialized'); this.logger.info('Handlers initialized');
@ -339,8 +339,10 @@ export class ServiceApplication {
this.logger.debug('Creating scheduled jobs from registered handlers...'); this.logger.debug('Creating scheduled jobs from registered handlers...');
const handlerRegistry = this.container.resolve<HandlerRegistry>('handlerRegistry'); const handlerRegistry = this.container.resolve<HandlerRegistry>('handlerRegistry');
const allHandlers = handlerRegistry.getAllHandlersWithSchedule(); const allHandlers = handlerRegistry.getAllHandlersWithSchedule();
this.logger.info(`Found ${allHandlers.size} handlers with scheduled jobs: ${Array.from(allHandlers.keys()).join(', ')}`); this.logger.info(
`Found ${allHandlers.size} handlers with scheduled jobs: ${Array.from(allHandlers.keys()).join(', ')}`
);
let totalScheduledJobs = 0; let totalScheduledJobs = 0;
for (const [handlerName, config] of allHandlers) { for (const [handlerName, config] of allHandlers) {
@ -368,9 +370,9 @@ export class ServiceApplication {
hasHandlerRegistry: !!handlerRegistry, hasHandlerRegistry: !!handlerRegistry,
registeredHandlers: handlerRegistry.getHandlerNames(), registeredHandlers: handlerRegistry.getHandlerNames(),
}); });
const queue = queueManager.getQueue(handlerName, { const queue = queueManager.getQueue(handlerName, {
handlerRegistry: handlerRegistry handlerRegistry: handlerRegistry,
}); });
for (const scheduledJob of config.scheduledJobs) { for (const scheduledJob of config.scheduledJobs) {
@ -395,7 +397,7 @@ export class ServiceApplication {
operation: scheduledJob.operation, operation: scheduledJob.operation,
hasOperation: !!handlerRegistry.getOperation(handlerName, scheduledJob.operation), hasOperation: !!handlerRegistry.getOperation(handlerName, scheduledJob.operation),
}); });
await queue.addScheduledJob( await queue.addScheduledJob(
scheduledJob.operation, scheduledJob.operation,
jobData, jobData,

View file

@ -7,9 +7,7 @@ import type { JobHandler, ScheduledJob } from '@stock-bot/types';
import type { import type {
HandlerConfiguration, HandlerConfiguration,
HandlerMetadata, HandlerMetadata,
OperationMetadata,
RegistryStats, RegistryStats,
ScheduleMetadata,
} from './types'; } from './types';
export class HandlerRegistry { export class HandlerRegistry {

View file

@ -1,3 +1,4 @@
import type { Collection } from 'mongodb';
import { createNamespacedCache } from '@stock-bot/cache'; import { createNamespacedCache } from '@stock-bot/cache';
import { getLogger } from '@stock-bot/logger'; import { getLogger } from '@stock-bot/logger';
import type { import type {
@ -10,7 +11,6 @@ import type {
ServiceTypes, ServiceTypes,
} from '@stock-bot/types'; } from '@stock-bot/types';
import { fetch } from '@stock-bot/utils'; import { fetch } from '@stock-bot/utils';
import type { Collection } from 'mongodb';
// Handler registry is now injected, not imported // Handler registry is now injected, not imported
import { createJobHandler } from '../utils/create-job-handler'; import { createJobHandler } from '../utils/create-job-handler';
@ -60,7 +60,7 @@ export abstract class BaseHandler implements IHandler {
const constructor = this.constructor as any; const constructor = this.constructor as any;
this.handlerName = this.handlerName =
constructor.__handlerName || handlerName || this.constructor.name.toLowerCase(); constructor.__handlerName || handlerName || this.constructor.name.toLowerCase();
// Flatten all services onto the handler instance // Flatten all services onto the handler instance
this.logger = getLogger(this.constructor.name); this.logger = getLogger(this.constructor.name);
this.cache = services.cache; this.cache = services.cache;
@ -71,7 +71,7 @@ export abstract class BaseHandler implements IHandler {
this.mongodb = services.mongodb; this.mongodb = services.mongodb;
this.postgres = services.postgres; this.postgres = services.postgres;
this.questdb = services.questdb; this.questdb = services.questdb;
// Get the specific queue for this handler // Get the specific queue for this handler
if (this.queueManager) { if (this.queueManager) {
this.queue = this.queueManager.getQueue(this.handlerName); this.queue = this.queueManager.getQueue(this.handlerName);
@ -336,9 +336,9 @@ export abstract class BaseHandler implements IHandler {
static extractMetadata(): HandlerMetadata | null { static extractMetadata(): HandlerMetadata | null {
const constructor = this as any; const constructor = this as any;
const handlerName = constructor.__handlerName; const handlerName = constructor.__handlerName;
if (!handlerName){ if (!handlerName) {
return null; return null;
} }
const operations = constructor.__operations || []; const operations = constructor.__operations || [];
const schedules = constructor.__schedules || []; const schedules = constructor.__schedules || [];

View file

@ -1,7 +1,6 @@
// Core exports // Core exports
export { Queue } from './queue'; export { Queue } from './queue';
export { QueueManager } from './queue-manager'; export { QueueManager } from './queue-manager';
export { SmartQueueManager } from './smart-queue-manager';
export { ServiceCache, createServiceCache } from './service-cache'; export { ServiceCache, createServiceCache } from './service-cache';
// Service utilities // Service utilities
export { export {

View file

@ -41,7 +41,7 @@ export class QueueManager {
private shutdownPromise: Promise<void> | null = null; private shutdownPromise: Promise<void> | null = null;
private config: QueueManagerConfig; private config: QueueManagerConfig;
private readonly logger: Logger; private readonly logger: Logger;
// Service discovery features // Service discovery features
private serviceName?: string; private serviceName?: string;
private queueRoutes = new Map<string, QueueRoute>(); private queueRoutes = new Map<string, QueueRoute>();
@ -59,7 +59,7 @@ export class QueueManager {
}, },
}; };
} }
this.config = config; this.config = config;
this.serviceName = config.serviceName; this.serviceName = config.serviceName;
this.handlerRegistry = handlerRegistry; this.handlerRegistry = handlerRegistry;
@ -80,7 +80,7 @@ export class QueueManager {
if (config.serviceName && config.autoDiscoverHandlers !== false && handlerRegistry) { if (config.serviceName && config.autoDiscoverHandlers !== false && handlerRegistry) {
this.discoverQueueRoutes(); this.discoverQueueRoutes();
} }
this.logger.info('QueueManager initialized', { this.logger.info('QueueManager initialized', {
redis: `${config.redis.host}:${config.redis.port}`, redis: `${config.redis.host}:${config.redis.port}`,
service: this.serviceName, service: this.serviceName,
@ -97,11 +97,11 @@ export class QueueManager {
getQueue(queueName: string, options: QueueOptions = {}): Queue { getQueue(queueName: string, options: QueueOptions = {}): Queue {
let fullQueueName = queueName; let fullQueueName = queueName;
let isOwnQueue = true; let isOwnQueue = true;
// Handle service namespacing if service name is configured // Handle service namespacing if service name is configured
if (this.serviceName) { if (this.serviceName) {
const parsed = parseQueueName(queueName); const parsed = parseQueueName(queueName);
if (parsed) { if (parsed) {
// Already in service:handler format // Already in service:handler format
fullQueueName = queueName; fullQueueName = queueName;
@ -111,7 +111,7 @@ export class QueueManager {
fullQueueName = getFullQueueName(this.serviceName, queueName); fullQueueName = getFullQueueName(this.serviceName, queueName);
isOwnQueue = true; isOwnQueue = true;
} }
// For cross-service queues, create without workers (producer-only) // For cross-service queues, create without workers (producer-only)
if (!isOwnQueue) { if (!isOwnQueue) {
options = { options = {
@ -122,10 +122,10 @@ export class QueueManager {
// For own service queues, include handler registry // For own service queues, include handler registry
options = { options = {
...options, ...options,
handlerRegistry: this.handlerRegistry handlerRegistry: this.handlerRegistry,
}; };
} }
queueName = fullQueueName; queueName = fullQueueName;
} }
// Return existing queue if it exists // Return existing queue if it exists
@ -487,9 +487,11 @@ export class QueueManager {
let workersStarted = 0; let workersStarted = 0;
const queues = this.queues; const queues = this.queues;
this.logger.info(`Starting workers for ${queues.size} queues: ${Array.from(queues.keys()).join(', ')} (service: ${this.serviceName})`); this.logger.info(
`Starting workers for ${queues.size} queues: ${Array.from(queues.keys()).join(', ')} (service: ${this.serviceName})`
);
for (const [queueName, queue] of queues) { for (const [queueName, queue] of queues) {
// If we have a service name, check if this queue belongs to us // If we have a service name, check if this queue belongs to us
if (this.serviceName) { if (this.serviceName) {
@ -504,7 +506,7 @@ export class QueueManager {
continue; continue;
} }
} }
const workerCount = this.config.defaultQueueOptions?.workers || 1; const workerCount = this.config.defaultQueueOptions?.workers || 1;
const concurrency = this.config.defaultQueueOptions?.concurrency || 1; const concurrency = this.config.defaultQueueOptions?.concurrency || 1;
@ -548,7 +550,7 @@ export class QueueManager {
getConfig(): Readonly<QueueManagerConfig> { getConfig(): Readonly<QueueManagerConfig> {
return { ...this.config }; return { ...this.config };
} }
/** /**
* Send a job to any queue (local or remote) * Send a job to any queue (local or remote)
* This is the main method for cross-service communication * This is the main method for cross-service communication
@ -564,7 +566,7 @@ export class QueueManager {
const queue = this.getQueue(targetQueue); const queue = this.getQueue(targetQueue);
return queue.add(operation, { handler: targetQueue, operation, payload }, options); return queue.add(operation, { handler: targetQueue, operation, payload }, options);
} }
// Resolve the target queue // Resolve the target queue
const route = this.resolveQueueRoute(targetQueue); const route = this.resolveQueueRoute(targetQueue);
if (!route) { if (!route) {
@ -582,7 +584,7 @@ export class QueueManager {
// Use a producer queue for cross-service sending // Use a producer queue for cross-service sending
const producerQueue = this.getProducerQueue(route.fullName); const producerQueue = this.getProducerQueue(route.fullName);
const jobData: JobData = { const jobData: JobData = {
handler: route.handler, handler: route.handler,
operation, operation,
@ -599,7 +601,7 @@ export class QueueManager {
return producerQueue.add(operation, jobData, options); return producerQueue.add(operation, jobData, options);
} }
/** /**
* Resolve a queue name to a route * Resolve a queue name to a route
*/ */
@ -640,7 +642,7 @@ export class QueueManager {
return null; return null;
} }
/** /**
* Get a producer queue for sending to other services * Get a producer queue for sending to other services
*/ */
@ -654,7 +656,7 @@ export class QueueManager {
} }
return this.producerQueues.get(queueName)!; return this.producerQueues.get(queueName)!;
} }
/** /**
* Discover all available queue routes from handler registry * Discover all available queue routes from handler registry
*/ */

View file

@ -48,7 +48,7 @@ export class Queue {
this.logger = logger || console; this.logger = logger || console;
this.handlerRegistry = config.handlerRegistry; this.handlerRegistry = config.handlerRegistry;
this.serviceName = config.serviceName; this.serviceName = config.serviceName;
this.logger.debug('Queue constructor called', { this.logger.debug('Queue constructor called', {
queueName, queueName,
serviceName: this.serviceName, serviceName: this.serviceName,
@ -180,7 +180,7 @@ export class Queue {
]); ]);
const isPaused = await this.bullQueue.isPaused(); const isPaused = await this.bullQueue.isPaused();
// Get actual active worker count from BullMQ // Get actual active worker count from BullMQ
const activeWorkerCount = await this.getActiveWorkerCount(); const activeWorkerCount = await this.getActiveWorkerCount();
@ -317,7 +317,7 @@ export class Queue {
// Add a name to identify the worker // Add a name to identify the worker
name: `${this.serviceName || 'unknown'}_worker_${i}`, name: `${this.serviceName || 'unknown'}_worker_${i}`,
}); });
this.logger.info(`Starting worker ${i + 1}/${workerCount} for queue`, { this.logger.info(`Starting worker ${i + 1}/${workerCount} for queue`, {
queueName: this.queueName, queueName: this.queueName,
workerName: worker.name, workerName: worker.name,
@ -380,14 +380,14 @@ export class Queue {
if (!this.handlerRegistry) { if (!this.handlerRegistry) {
throw new Error('Handler registry not configured for worker processing'); throw new Error('Handler registry not configured for worker processing');
} }
this.logger.debug('Looking up handler in registry', { this.logger.debug('Looking up handler in registry', {
handler, handler,
operation, operation,
queueName: this.queueName, queueName: this.queueName,
registeredHandlers: this.handlerRegistry.getHandlerNames(), registeredHandlers: this.handlerRegistry.getHandlerNames(),
}); });
const jobHandler = this.handlerRegistry.getOperation(handler, operation); const jobHandler = this.handlerRegistry.getOperation(handler, operation);
if (!jobHandler) { if (!jobHandler) {
@ -424,7 +424,7 @@ export class Queue {
this.logger.warn('Workers already started for queue', { queueName: this.queueName }); this.logger.warn('Workers already started for queue', { queueName: this.queueName });
return; return;
} }
this.logger.info('Starting workers manually', { this.logger.info('Starting workers manually', {
queueName: this.queueName, queueName: this.queueName,
workerCount, workerCount,
@ -457,9 +457,9 @@ export class Queue {
const workers = await this.bullQueue.getWorkers(); const workers = await this.bullQueue.getWorkers();
return workers; return workers;
} catch (error) { } catch (error) {
this.logger.error('Failed to get active workers', { this.logger.error('Failed to get active workers', {
queueName: this.queueName, queueName: this.queueName,
error error,
}); });
return []; return [];
} }
@ -473,9 +473,9 @@ export class Queue {
const workers = await this.bullQueue.getWorkers(); const workers = await this.bullQueue.getWorkers();
return workers.length; return workers.length;
} catch (error) { } catch (error) {
this.logger.error('Failed to get active worker count', { this.logger.error('Failed to get active worker count', {
queueName: this.queueName, queueName: this.queueName,
error error,
}); });
return 0; return 0;
} }
@ -484,14 +484,16 @@ export class Queue {
/** /**
* Get detailed worker information * Get detailed worker information
*/ */
async getWorkerDetails(): Promise<Array<{ async getWorkerDetails(): Promise<
id: string; Array<{
name?: string; id: string;
addr?: string; name?: string;
age?: number; addr?: string;
idle?: number; age?: number;
started?: number; idle?: number;
}>> { started?: number;
}>
> {
try { try {
const workers = await this.bullQueue.getWorkers(); const workers = await this.bullQueue.getWorkers();
return workers.map(worker => ({ return workers.map(worker => ({
@ -503,13 +505,11 @@ export class Queue {
started: typeof worker.started === 'string' ? parseInt(worker.started) : worker.started, started: typeof worker.started === 'string' ? parseInt(worker.started) : worker.started,
})); }));
} catch (error) { } catch (error) {
this.logger.error('Failed to get worker details', { this.logger.error('Failed to get worker details', {
queueName: this.queueName, queueName: this.queueName,
error error,
}); });
return []; return [];
} }
} }
} }

View file

@ -1,18 +0,0 @@
// SmartQueueManager has been merged into QueueManager
// This file is kept for backward compatibility
import { QueueManager } from './queue-manager';
import type { SmartQueueConfig } from './types';
import type { HandlerRegistry } from '@stock-bot/handler-registry';
import type { Logger } from '@stock-bot/logger';
/**
* @deprecated Use QueueManager directly with serviceName config
* SmartQueueManager functionality has been merged into QueueManager
*/
export class SmartQueueManager extends QueueManager {
constructor(config: SmartQueueConfig, handlerRegistry?: HandlerRegistry, logger?: Logger) {
// SmartQueueConfig already has serviceName, just pass it to QueueManager
super(config, handlerRegistry, logger);
}
}