updates
This commit is contained in:
parent
d3ef73ae00
commit
a2fa08de88
8 changed files with 72 additions and 68 deletions
|
|
@ -1,17 +1,10 @@
|
||||||
import { Queue, type Job } from 'bullmq';
|
import { Queue, type Job } from 'bullmq';
|
||||||
import { getLogger } from '@stock-bot/logger';
|
import { getLogger } from '@stock-bot/logger';
|
||||||
import type { JobData } from './types';
|
import type { JobData, DLQConfig, RedisConfig } from './types';
|
||||||
import { getRedisConnection } from './utils';
|
import { getRedisConnection } from './utils';
|
||||||
|
|
||||||
const logger = getLogger('dlq-handler');
|
const logger = getLogger('dlq-handler');
|
||||||
|
|
||||||
export interface DLQConfig {
|
|
||||||
maxRetries?: number;
|
|
||||||
retryDelay?: number;
|
|
||||||
alertThreshold?: number;
|
|
||||||
cleanupAge?: number; // hours
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DeadLetterQueueHandler {
|
export class DeadLetterQueueHandler {
|
||||||
private dlq: Queue;
|
private dlq: Queue;
|
||||||
private config: Required<DLQConfig>;
|
private config: Required<DLQConfig>;
|
||||||
|
|
@ -19,7 +12,7 @@ export class DeadLetterQueueHandler {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private mainQueue: Queue,
|
private mainQueue: Queue,
|
||||||
private connection: any,
|
private connection: RedisConfig,
|
||||||
config: DLQConfig = {}
|
config: DLQConfig = {}
|
||||||
) {
|
) {
|
||||||
this.config = {
|
this.config = {
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,12 @@
|
||||||
export * from './batch-processor';
|
// Core exports
|
||||||
export * from './handler-registry';
|
export { Queue, type QueueWorkerConfig } from './queue';
|
||||||
export * from './queue-manager';
|
|
||||||
export * from './queue-factory';
|
|
||||||
export * from './types';
|
|
||||||
export * from './dlq-handler';
|
|
||||||
export * from './queue-metrics';
|
|
||||||
export * from './rate-limiter';
|
|
||||||
|
|
||||||
// Re-export commonly used functions
|
|
||||||
export { processBatchJob, processItems } from './batch-processor';
|
|
||||||
|
|
||||||
export { QueueManager } from './queue-manager';
|
export { QueueManager } from './queue-manager';
|
||||||
export { Queue, type QueueConfig } from './queue';
|
|
||||||
|
|
||||||
export { handlerRegistry } from './handler-registry';
|
export { handlerRegistry } from './handler-registry';
|
||||||
|
|
||||||
// Re-export queue factory functions
|
// Batch processing
|
||||||
|
export { processBatchJob, processItems } from './batch-processor';
|
||||||
|
|
||||||
|
// Queue factory functions
|
||||||
export {
|
export {
|
||||||
initializeQueueSystem,
|
initializeQueueSystem,
|
||||||
getQueue,
|
getQueue,
|
||||||
|
|
@ -25,17 +16,50 @@ export {
|
||||||
shutdownAllQueues
|
shutdownAllQueues
|
||||||
} from './queue-factory';
|
} from './queue-factory';
|
||||||
|
|
||||||
// Re-export types for convenience
|
// DLQ handling
|
||||||
|
export { DLQHandler } from './dlq-handler';
|
||||||
|
|
||||||
|
// Metrics
|
||||||
|
export { QueueMetricsCollector } from './queue-metrics';
|
||||||
|
|
||||||
|
// Rate limiting
|
||||||
|
export { QueueRateLimiter } from './rate-limiter';
|
||||||
|
|
||||||
|
// Types
|
||||||
export type {
|
export type {
|
||||||
|
// Core types
|
||||||
|
JobData,
|
||||||
|
JobOptions,
|
||||||
|
QueueOptions,
|
||||||
|
QueueStats,
|
||||||
|
GlobalStats,
|
||||||
|
|
||||||
|
// Batch processing types
|
||||||
BatchResult,
|
BatchResult,
|
||||||
JobHandler,
|
|
||||||
ProcessOptions,
|
ProcessOptions,
|
||||||
|
BatchJobData,
|
||||||
|
|
||||||
|
// Handler types
|
||||||
|
JobHandler,
|
||||||
HandlerConfig,
|
HandlerConfig,
|
||||||
HandlerConfigWithSchedule,
|
HandlerConfigWithSchedule,
|
||||||
HandlerInitializer,
|
HandlerInitializer,
|
||||||
|
|
||||||
|
// Configuration types
|
||||||
|
RedisConfig,
|
||||||
QueueConfig,
|
QueueConfig,
|
||||||
ScheduledJob,
|
QueueManagerConfig,
|
||||||
|
|
||||||
|
// Rate limiting types
|
||||||
RateLimitConfig,
|
RateLimitConfig,
|
||||||
RateLimitRule,
|
RateLimitRule,
|
||||||
|
|
||||||
|
// DLQ types
|
||||||
DLQConfig,
|
DLQConfig,
|
||||||
|
DLQJobInfo,
|
||||||
|
|
||||||
|
// Scheduled job types
|
||||||
|
ScheduledJob,
|
||||||
|
ScheduleConfig,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { getLogger } from '@stock-bot/logger';
|
||||||
import { QueueManager } from './queue-manager';
|
import { QueueManager } from './queue-manager';
|
||||||
import { Queue } from './queue';
|
import { Queue } from './queue';
|
||||||
import { processItems } from './batch-processor';
|
import { processItems } from './batch-processor';
|
||||||
import type { ProcessOptions, BatchResult, QueueManagerConfig } from './types';
|
import type { ProcessOptions, BatchResult, QueueManagerConfig, RedisConfig, JobOptions } from './types';
|
||||||
|
|
||||||
const logger = getLogger('queue-factory');
|
const logger = getLogger('queue-factory');
|
||||||
|
|
||||||
|
|
@ -11,8 +11,8 @@ const logger = getLogger('queue-factory');
|
||||||
* This now uses the singleton QueueManager pattern
|
* This now uses the singleton QueueManager pattern
|
||||||
*/
|
*/
|
||||||
export async function initializeQueueSystem(config: {
|
export async function initializeQueueSystem(config: {
|
||||||
redis: any;
|
redis: RedisConfig;
|
||||||
defaultJobOptions?: any;
|
defaultJobOptions?: JobOptions;
|
||||||
workers?: number;
|
workers?: number;
|
||||||
concurrency?: number;
|
concurrency?: number;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
import { getLogger } from '@stock-bot/logger';
|
import { getLogger } from '@stock-bot/logger';
|
||||||
import { QueueRateLimiter } from './rate-limiter';
|
import { QueueRateLimiter } from './rate-limiter';
|
||||||
import { Queue, type QueueConfig } from './queue';
|
import { Queue, type QueueWorkerConfig } from './queue';
|
||||||
import { CacheProvider, createCache } from '@stock-bot/cache';
|
import { CacheProvider, createCache } from '@stock-bot/cache';
|
||||||
import type {
|
import type {
|
||||||
QueueManagerConfig,
|
QueueManagerConfig,
|
||||||
QueueOptions,
|
QueueOptions,
|
||||||
GlobalStats,
|
GlobalStats,
|
||||||
QueueStats,
|
QueueStats,
|
||||||
RateLimitRule
|
RateLimitRule,
|
||||||
|
RedisConfig
|
||||||
} from './types';
|
} from './types';
|
||||||
import { getRedisConnection } from './utils';
|
import { getRedisConnection } from './utils';
|
||||||
|
|
||||||
|
|
@ -22,7 +23,7 @@ export class QueueManager {
|
||||||
private queues = new Map<string, Queue>();
|
private queues = new Map<string, Queue>();
|
||||||
private caches = new Map<string, CacheProvider>();
|
private caches = new Map<string, CacheProvider>();
|
||||||
private rateLimiter?: QueueRateLimiter;
|
private rateLimiter?: QueueRateLimiter;
|
||||||
private redisConnection: any;
|
private redisConnection: ReturnType<typeof getRedisConnection>;
|
||||||
private isShuttingDown = false;
|
private isShuttingDown = false;
|
||||||
private isInitialized = false;
|
private isInitialized = false;
|
||||||
|
|
||||||
|
|
@ -93,7 +94,7 @@ export class QueueManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prepare queue configuration
|
// Prepare queue configuration
|
||||||
const queueConfig: QueueConfig = {
|
const queueConfig: QueueWorkerConfig = {
|
||||||
workers: mergedOptions.workers,
|
workers: mergedOptions.workers,
|
||||||
concurrency: mergedOptions.concurrency,
|
concurrency: mergedOptions.concurrency,
|
||||||
startWorker: mergedOptions.workers && mergedOptions.workers > 0,
|
startWorker: mergedOptions.workers && mergedOptions.workers > 0,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { Queue as BullQueue, Worker, QueueEvents, type Job } from 'bullmq';
|
import { Queue as BullQueue, Worker, QueueEvents, type Job } from 'bullmq';
|
||||||
import { getLogger } from '@stock-bot/logger';
|
import { getLogger } from '@stock-bot/logger';
|
||||||
import { handlerRegistry } from './handler-registry';
|
import { handlerRegistry } from './handler-registry';
|
||||||
import type { JobData, JobOptions, QueueStats } from './types';
|
import type { JobData, JobOptions, QueueStats, RedisConfig } from './types';
|
||||||
import { getRedisConnection } from './utils';
|
import { getRedisConnection } from './utils';
|
||||||
|
|
||||||
const logger = getLogger('queue');
|
const logger = getLogger('queue');
|
||||||
|
|
||||||
export interface QueueConfig {
|
export interface QueueWorkerConfig {
|
||||||
workers?: number;
|
workers?: number;
|
||||||
concurrency?: number;
|
concurrency?: number;
|
||||||
startWorker?: boolean;
|
startWorker?: boolean;
|
||||||
|
|
@ -21,13 +21,13 @@ export class Queue {
|
||||||
private workers: Worker[] = [];
|
private workers: Worker[] = [];
|
||||||
private queueEvents?: QueueEvents;
|
private queueEvents?: QueueEvents;
|
||||||
private queueName: string;
|
private queueName: string;
|
||||||
private redisConfig: any;
|
private redisConfig: RedisConfig;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
queueName: string,
|
queueName: string,
|
||||||
redisConfig: any,
|
redisConfig: RedisConfig,
|
||||||
defaultJobOptions: JobOptions = {},
|
defaultJobOptions: JobOptions = {},
|
||||||
config: QueueConfig = {}
|
config: QueueWorkerConfig = {}
|
||||||
) {
|
) {
|
||||||
this.queueName = queueName;
|
this.queueName = queueName;
|
||||||
this.redisConfig = redisConfig;
|
this.redisConfig = redisConfig;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,19 @@
|
||||||
import { RateLimiterRedis, RateLimiterRes } from 'rate-limiter-flexible';
|
import { RateLimiterRedis, RateLimiterRes } from 'rate-limiter-flexible';
|
||||||
import { getLogger } from '@stock-bot/logger';
|
import { getLogger } from '@stock-bot/logger';
|
||||||
|
import type { RateLimitConfig as BaseRateLimitConfig, RateLimitRule } from './types';
|
||||||
|
|
||||||
const logger = getLogger('rate-limiter');
|
const logger = getLogger('rate-limiter');
|
||||||
|
|
||||||
export interface RateLimitConfig {
|
// Extend the base config to add rate-limiter specific fields
|
||||||
points: number; // Number of requests
|
export interface RateLimitConfig extends BaseRateLimitConfig {
|
||||||
duration: number; // Per duration in seconds
|
|
||||||
blockDuration?: number; // Block duration in seconds
|
|
||||||
keyPrefix?: string;
|
keyPrefix?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RateLimitRule {
|
|
||||||
level: 'global' | 'queue' | 'handler' | 'operation';
|
|
||||||
queueName?: string; // For queue-level limits
|
|
||||||
handler?: string; // For handler-level limits
|
|
||||||
operation?: string; // For operation-level limits (most specific)
|
|
||||||
config: RateLimitConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class QueueRateLimiter {
|
export class QueueRateLimiter {
|
||||||
private limiters = new Map<string, RateLimiterRedis>();
|
private limiters = new Map<string, RateLimiterRedis>();
|
||||||
private rules: RateLimitRule[] = [];
|
private rules: RateLimitRule[] = [];
|
||||||
|
|
||||||
constructor(private redisClient: any) {}
|
constructor(private redisClient: ReturnType<typeof import('./utils').getRedisConnection>) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a rate limit rule
|
* Add a rate limit rule
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// Types for queue operations
|
// Types for queue operations
|
||||||
export interface JobData {
|
export interface JobData<T = unknown> {
|
||||||
type?: string;
|
type?: string;
|
||||||
handler: string;
|
handler: string;
|
||||||
operation: string;
|
operation: string;
|
||||||
payload: any;
|
payload: T;
|
||||||
priority?: number;
|
priority?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -19,8 +19,6 @@ export interface ProcessOptions {
|
||||||
// Job routing information
|
// Job routing information
|
||||||
handler?: string;
|
handler?: string;
|
||||||
operation?: string;
|
operation?: string;
|
||||||
// Optional queue for overloaded function signatures
|
|
||||||
queue?: any; // QueueManager reference
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BatchResult {
|
export interface BatchResult {
|
||||||
|
|
@ -33,8 +31,8 @@ export interface BatchResult {
|
||||||
|
|
||||||
// New improved types for the refactored architecture
|
// New improved types for the refactored architecture
|
||||||
export interface RedisConfig {
|
export interface RedisConfig {
|
||||||
host?: string;
|
host: string;
|
||||||
port?: number;
|
port: number;
|
||||||
password?: string;
|
password?: string;
|
||||||
db?: number;
|
db?: number;
|
||||||
}
|
}
|
||||||
|
|
@ -96,14 +94,14 @@ export interface QueueConfig extends QueueManagerConfig {
|
||||||
enableMetrics?: boolean;
|
enableMetrics?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JobHandler {
|
export interface JobHandler<TPayload = unknown, TResult = unknown> {
|
||||||
(payload: any): Promise<any>;
|
(payload: TPayload): Promise<TResult>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ScheduledJob {
|
export interface ScheduledJob<T = unknown> {
|
||||||
type: string;
|
type: string;
|
||||||
operation: string;
|
operation: string;
|
||||||
payload: any;
|
payload: T;
|
||||||
cronPattern: string;
|
cronPattern: string;
|
||||||
priority?: number;
|
priority?: number;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
|
import type { RedisConfig } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Redis connection configuration with retry settings
|
* Get Redis connection configuration with retry settings
|
||||||
*/
|
*/
|
||||||
export function getRedisConnection(config: {
|
export function getRedisConnection(config: RedisConfig) {
|
||||||
host: string;
|
|
||||||
port: number;
|
|
||||||
password?: string;
|
|
||||||
db?: number;
|
|
||||||
}) {
|
|
||||||
const isTest = process.env.NODE_ENV === 'test' || process.env.BUNIT === '1';
|
const isTest = process.env.NODE_ENV === 'test' || process.env.BUNIT === '1';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue