testing ratelimit
This commit is contained in:
parent
95b1381480
commit
a616c92656
14 changed files with 411 additions and 3 deletions
|
|
@ -101,6 +101,8 @@ export class HandlerScanner {
|
|||
const schedules = HandlerClass.__schedules || [];
|
||||
const isDisabled = HandlerClass.__disabled || false;
|
||||
const disabledOperations = HandlerClass.__disabledOperations || [];
|
||||
const handlerRateLimit = HandlerClass.__handlerRateLimit || null;
|
||||
const operationRateLimits = HandlerClass.__rateLimits || {};
|
||||
|
||||
if (isDisabled) {
|
||||
this.logger.debug('Skipping disabled handler', { handlerName });
|
||||
|
|
@ -131,13 +133,14 @@ export class HandlerScanner {
|
|||
return !isDisabled;
|
||||
});
|
||||
|
||||
// Build metadata
|
||||
// Build metadata with rate limit information
|
||||
const metadata: HandlerMetadata = {
|
||||
name: handlerName,
|
||||
service: this.options.serviceName,
|
||||
operations: enabledOperations.map((op: any) => ({
|
||||
name: op.name,
|
||||
method: op.method,
|
||||
rateLimit: operationRateLimits[op.method] || null,
|
||||
})),
|
||||
schedules: enabledSchedules.map((schedule: any) => ({
|
||||
operation: schedule.operation,
|
||||
|
|
@ -148,6 +151,7 @@ export class HandlerScanner {
|
|||
payload: schedule.payload,
|
||||
batch: schedule.batch,
|
||||
})),
|
||||
rateLimit: handlerRateLimit,
|
||||
};
|
||||
|
||||
// Build configuration with operation handlers
|
||||
|
|
|
|||
|
|
@ -5,6 +5,15 @@
|
|||
|
||||
import type { JobHandler, ScheduledJob } from '@stock-bot/types';
|
||||
|
||||
/**
|
||||
* Rate limit configuration
|
||||
*/
|
||||
export interface RateLimitConfig {
|
||||
points: number;
|
||||
duration: number;
|
||||
blockDuration?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata for a single operation within a handler
|
||||
*/
|
||||
|
|
@ -12,6 +21,7 @@ export interface OperationMetadata {
|
|||
name: string;
|
||||
method: string;
|
||||
description?: string;
|
||||
rateLimit?: RateLimitConfig | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -35,6 +45,7 @@ export interface HandlerMetadata {
|
|||
schedules?: ScheduleMetadata[];
|
||||
version?: string;
|
||||
description?: string;
|
||||
rateLimit?: RateLimitConfig | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
56
libs/core/handlers/src/decorators/rate-limit.ts
Normal file
56
libs/core/handlers/src/decorators/rate-limit.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* Rate limit configuration for handlers and operations
|
||||
*/
|
||||
export interface RateLimitConfig {
|
||||
points: number; // Number of allowed requests
|
||||
duration: number; // Time window in seconds
|
||||
blockDuration?: number; // How long to block after limit is hit (seconds)
|
||||
}
|
||||
|
||||
/**
|
||||
* RateLimit decorator - configures rate limiting for handlers or operations
|
||||
*
|
||||
* Can be applied to:
|
||||
* - Classes: Sets default rate limit for all operations in the handler
|
||||
* - Methods: Sets specific rate limit for individual operations (overrides handler-level)
|
||||
*
|
||||
* @param config Rate limit configuration
|
||||
*
|
||||
* @example
|
||||
* // Handler-level rate limit
|
||||
* @Handler('myHandler')
|
||||
* @RateLimit({ points: 100, duration: 60 })
|
||||
* class MyHandler extends BaseHandler {
|
||||
* // All operations inherit the 100/minute limit
|
||||
* }
|
||||
*
|
||||
* @example
|
||||
* // Operation-specific rate limit
|
||||
* @Operation('fetch-data')
|
||||
* @RateLimit({ points: 10, duration: 60, blockDuration: 30 })
|
||||
* async fetchData() {
|
||||
* // This operation is limited to 10/minute
|
||||
* }
|
||||
*/
|
||||
export function RateLimit(config: RateLimitConfig) {
|
||||
return function (target: any, propertyKey?: string, descriptor?: PropertyDescriptor): any {
|
||||
if (propertyKey) {
|
||||
// Method decorator - operation-specific rate limit
|
||||
const constructor = target.constructor;
|
||||
|
||||
// Initialize rate limits array if not exists
|
||||
if (!constructor.__rateLimits) {
|
||||
constructor.__rateLimits = {};
|
||||
}
|
||||
|
||||
// Store rate limit config for this operation
|
||||
constructor.__rateLimits[propertyKey] = config;
|
||||
|
||||
return descriptor;
|
||||
} else {
|
||||
// Class decorator - handler-level rate limit
|
||||
(target as any).__handlerRateLimit = config;
|
||||
return target;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -7,6 +7,8 @@ export {
|
|||
ScheduledOperation,
|
||||
Disabled,
|
||||
} from './decorators/decorators';
|
||||
export { RateLimit } from './decorators/rate-limit';
|
||||
export type { RateLimitConfig } from './decorators/rate-limit';
|
||||
export { createJobHandler } from './utils/create-job-handler';
|
||||
|
||||
// Re-export commonly used types from @stock-bot/types for convenience
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue