nest-scheduler-engine 2.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/README.md +225 -2
- package/dist/constants.d.ts +29 -0
- package/dist/constants.js +33 -0
- package/dist/constants.js.map +1 -0
- package/dist/decorators/cron.decorator.d.ts +11 -0
- package/dist/decorators/cron.decorator.js +12 -0
- package/dist/decorators/cron.decorator.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/middleware.interface.d.ts +14 -0
- package/dist/interfaces/middleware.interface.js +3 -0
- package/dist/interfaces/middleware.interface.js.map +1 -0
- package/dist/migrations/index.js +7 -0
- package/dist/migrations/index.js.map +1 -1
- package/dist/models/event-type.model.d.ts +2 -0
- package/dist/models/event-type.model.js.map +1 -1
- package/dist/scheduler.module.js +13 -6
- package/dist/scheduler.module.js.map +1 -1
- package/dist/services/concurrency-manager.service.d.ts +11 -0
- package/dist/services/concurrency-manager.service.js +103 -0
- package/dist/services/concurrency-manager.service.js.map +1 -0
- package/dist/services/cron-discovery.service.d.ts +15 -0
- package/dist/services/cron-discovery.service.js +105 -0
- package/dist/services/cron-discovery.service.js.map +1 -0
- package/dist/services/dispatcher.service.d.ts +4 -0
- package/dist/services/dispatcher.service.js +59 -3
- package/dist/services/dispatcher.service.js.map +1 -1
- package/dist/services/event-manager.service.d.ts +2 -1
- package/dist/services/event-manager.service.js +80 -4
- package/dist/services/event-manager.service.js.map +1 -1
- package/dist/services/polling-engine.service.d.ts +5 -1
- package/dist/services/polling-engine.service.js +83 -10
- package/dist/services/polling-engine.service.js.map +1 -1
- package/dist/services/scheduler.service.d.ts +7 -3
- package/dist/services/scheduler.service.js +10 -4
- package/dist/services/scheduler.service.js.map +1 -1
- package/dist/types/inputs.d.ts +5 -0
- package/dist/utils/circuit-breaker.js +2 -1
- package/dist/utils/circuit-breaker.js.map +1 -1
- package/dist/utils/cron-to-rrule.d.ts +1 -0
- package/dist/utils/cron-to-rrule.js +106 -0
- package/dist/utils/cron-to-rrule.js.map +1 -0
- package/dist/utils/graceful-shutdown.js +2 -1
- package/dist/utils/graceful-shutdown.js.map +1 -1
- package/dist/utils/retry-helper.js +3 -2
- package/dist/utils/retry-helper.js.map +1 -1
- package/dist/utils/rrule-helper.js +5 -5
- package/dist/utils/rrule-helper.js.map +1 -1
- package/dist/utils/security.js +4 -3
- package/dist/utils/security.js.map +1 -1
- package/dist/utils/validation.js +6 -5
- package/dist/utils/validation.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -120,6 +120,48 @@ This is a major release with comprehensive production-grade features, fault tole
|
|
|
120
120
|
- Added inline documentation for all new utilities
|
|
121
121
|
- Test examples and patterns
|
|
122
122
|
|
|
123
|
+
## [2.1.0] - 2026-04-12
|
|
124
|
+
|
|
125
|
+
### Added
|
|
126
|
+
|
|
127
|
+
- **Declarative Cron Jobs**: new `@Cron` method decorator to declare cron-style schedules directly on provider methods. The decorator converts a 5-field cron expression into an RRULE and schedules a recurring event using the engine. Decorator options include `name`, `timezone`, `payload`, `startDate`, `endDate`, `enabled`, and `recoverMissedExecutions`.
|
|
128
|
+
|
|
129
|
+
### Notes
|
|
130
|
+
|
|
131
|
+
- Initial implementation performs in-memory discovery at bootstrap and schedules idempotently using `cron:<eventTypeName>` idempotency keys. Persistent cron metadata, advanced missed-execution recovery, and full timezone persistence are planned next.
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
## [3.0.0] - 2026-04-12
|
|
135
|
+
|
|
136
|
+
### Added
|
|
137
|
+
|
|
138
|
+
- **Priority & Concurrency Control**: Added `priority` and `maxConcurrency` fields to event types to control execution order and limits per event type.
|
|
139
|
+
- **Bulk Scheduling API**: Implemented `scheduleEvents` with transaction support and `PARTIAL_SUCCESS` mode for partial failures.
|
|
140
|
+
- **Middleware System**: Added a middleware pipeline allowing injection of custom logic (logging, tracing, auth, metrics) into the handler execution path.
|
|
141
|
+
- **Polling Engine Enhancements**: Polling now orders events by priority and enforces concurrency limits while selecting events.
|
|
142
|
+
- **Concurrency Manager Service**: New `ConcurrencyManager` to track and enforce per-event-type concurrency counts across instances.
|
|
143
|
+
- **Tests & Docs**: Unit tests added for bulk scheduling, middleware, and priority/concurrency; README updated with examples.
|
|
144
|
+
|
|
145
|
+
### Changed
|
|
146
|
+
|
|
147
|
+
- Package version bumped to `3.0.0` with Node.js >= 18 requirement retained.
|
|
148
|
+
|
|
149
|
+
### Notes
|
|
150
|
+
|
|
151
|
+
- These features enable more predictable scheduling in mixed workloads (high-priority vs background jobs) and safer horizontal scaling by enforcing concurrency limits.
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
## [3.1.0] - 2026-04-12
|
|
155
|
+
|
|
156
|
+
### Added
|
|
157
|
+
|
|
158
|
+
- **Declarative Cron Jobs**: `@Cron` method decorator to declare cron-style schedules directly on provider methods. The decorator converts a 5-field cron expression into an RRULE and schedules a recurring event using the engine. Decorator options include `name`, `timezone`, `payload`, `startDate`, `endDate`, `enabled`, and `recoverMissedExecutions`.
|
|
159
|
+
|
|
160
|
+
### Notes
|
|
161
|
+
|
|
162
|
+
- Initial implementation performs discovery at module init and schedules idempotently using `cron:<eventTypeName>` idempotency keys. Persistent cron metadata, advanced missed-execution recovery, and full timezone persistence are planned next.
|
|
163
|
+
|
|
164
|
+
|
|
123
165
|
### Migration Guide from 1.x to 2.x
|
|
124
166
|
|
|
125
167
|
#### Breaking Changes
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A production-grade, event-type-driven scheduling engine for NestJS applications. This package provides a flexible and scalable solution for scheduling and executing recurring and one-time events with built-in fault tolerance, retry logic, dead-letter handling, and RRULE support (RFC 5545).
|
|
4
4
|
|
|
5
|
-
> **Version
|
|
5
|
+
> **Version 3.1.0** - Adds declarative Cron decorator and production features (priority/concurrency). See [CHANGELOG.md](CHANGELOG.md) for details and migration guide.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
@@ -14,8 +14,9 @@ A production-grade, event-type-driven scheduling engine for NestJS applications.
|
|
|
14
14
|
- **RRULE Support** - RFC 5545 compliant recurrence rules for complex recurring schedules.
|
|
15
15
|
- **Framework-Agnostic Core** - Core logic is framework-agnostic with a NestJS wrapper module.
|
|
16
16
|
- **Horizontal Scalability** - Multiple instances can run concurrently with database-level locking.
|
|
17
|
+
- **Persistent Storage** - All scheduler state (event types, event instances, execution history, dead letters, and cron metadata) is persisted in the consumer database via the `IDatabaseAdapter` you provide. This ensures scheduled jobs survive process restarts and multiple instances coordinate safely using database locks and idempotency keys.
|
|
17
18
|
|
|
18
|
-
### Production Features (
|
|
19
|
+
### Production Features (v3.0.0+)
|
|
19
20
|
- **Fault Tolerance** - Circuit breaker pattern prevents cascading failures and protects downstream systems.
|
|
20
21
|
- **Advanced Retry** - Exponential backoff with jitter and capped delays for optimal retry behavior.
|
|
21
22
|
- **Health Checks** - Component-level health monitoring for database, queue, poller, and dispatcher.
|
|
@@ -27,6 +28,9 @@ A production-grade, event-type-driven scheduling engine for NestJS applications.
|
|
|
27
28
|
- **Observability Hooks** - Lifecycle hooks for monitoring, alerting, and audit logging.
|
|
28
29
|
- **Edge Case Handling** - Comprehensive validation for dates, RRULE, payloads, state transitions, and more. See [EDGE_CASES.md](EDGE_CASES.md).
|
|
29
30
|
|
|
31
|
+
- **Persistent DB-backed State** - Scheduler persists event types, instances, execution history, and dead letters via the provided `IDatabaseAdapter`. Persistent state enables recovery after restarts, safe horizontal scaling, and idempotent scheduling operations (use shipped migrations and `tablePrefix` to namespace tables).
|
|
32
|
+
|
|
33
|
+
|
|
30
34
|
## Installation
|
|
31
35
|
|
|
32
36
|
```bash
|
|
@@ -278,6 +282,32 @@ export class NotificationService {
|
|
|
278
282
|
}
|
|
279
283
|
```
|
|
280
284
|
|
|
285
|
+
### Declarative Cron Jobs (new)
|
|
286
|
+
|
|
287
|
+
You can declare cron-style scheduled jobs using the `@Cron` method decorator. The decorator converts a standard 5-field cron expression into an RRULE and schedules it through the engine.
|
|
288
|
+
|
|
289
|
+
Example:
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import { Injectable } from '@nestjs/common';
|
|
293
|
+
import { Cron } from 'nest-scheduler-engine/decorators/cron.decorator';
|
|
294
|
+
|
|
295
|
+
@Injectable()
|
|
296
|
+
export class JobsService {
|
|
297
|
+
@Cron('0 9 * * *', { name: 'DAILY_SUMMARY', timezone: 'America/Los_Angeles' })
|
|
298
|
+
async handleDailySummary() {
|
|
299
|
+
// business logic executed by the scheduler engine
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Notes:
|
|
305
|
+
- The decorator converts the cron expression to an RRULE (RFC 5545) using an internal converter and schedules a recurring event.
|
|
306
|
+
- Each decorated method is registered as an event handler and mapped to a unique event type.
|
|
307
|
+
- Scheduling is idempotent: by default a cron job uses an idempotency key `cron:<eventTypeName>` to avoid duplicate scheduled instances on bootstrap.
|
|
308
|
+
- The discovery currently runs at module init and will create the event type and schedule the recurring event if it does not already exist.
|
|
309
|
+
- Advanced features (persistent cron metadata table, timezone persistence, missed-execution recovery and versioning) are planned and will be enabled progressively; basic decorator + idempotent scheduling is available now.
|
|
310
|
+
|
|
281
311
|
## API Reference
|
|
282
312
|
|
|
283
313
|
### SchedulerService
|
|
@@ -310,6 +340,193 @@ Main service for interacting with the scheduler.
|
|
|
310
340
|
- `listDeadLetters(): Promise<DeadLetter[]>`
|
|
311
341
|
- `retryDeadLetter(id: string): Promise<EventInstance>`
|
|
312
342
|
|
|
343
|
+
#### Bulk Scheduling (v2.1.0+)
|
|
344
|
+
|
|
345
|
+
- `scheduleEvents(inputs: ScheduleEventInput[], options?: BulkScheduleOptions): Promise<EventInstance[]>`
|
|
346
|
+
|
|
347
|
+
#### Middleware
|
|
348
|
+
|
|
349
|
+
- `use(middleware: MiddlewareFunction | IMiddleware): void`
|
|
350
|
+
|
|
351
|
+
## High-ROI Features (v2.1.0+)
|
|
352
|
+
|
|
353
|
+
### Priority + Concurrency Control
|
|
354
|
+
|
|
355
|
+
Control execution priority and limit concurrent executions per event type.
|
|
356
|
+
|
|
357
|
+
**Create Event Types with Priority:**
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
// High priority events execute first
|
|
361
|
+
const urgentEventType = await scheduler.createEventType({
|
|
362
|
+
name: 'URGENT_NOTIFICATION',
|
|
363
|
+
description: 'Critical user notifications',
|
|
364
|
+
priority: 10, // Higher = higher priority (default: 0)
|
|
365
|
+
maxConcurrency: 5, // Max 5 concurrent executions (default: null = unlimited)
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// Low priority background jobs
|
|
369
|
+
const backgroundEventType = await scheduler.createEventType({
|
|
370
|
+
name: 'BACKGROUND_SYNC',
|
|
371
|
+
description: 'Background data sync',
|
|
372
|
+
priority: 1, // Lower priority
|
|
373
|
+
maxConcurrency: 2, // Limit to 2 concurrent executions
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**How it works:**
|
|
378
|
+
- Polling engine orders events by `priority DESC, next_run_at ASC`
|
|
379
|
+
- Higher priority events are picked first
|
|
380
|
+
- `maxConcurrency` prevents resource exhaustion:
|
|
381
|
+
- `null` or `undefined` = unlimited (default)
|
|
382
|
+
- `> 0` = maximum concurrent executions
|
|
383
|
+
- `= 0` = event type disabled
|
|
384
|
+
- Prevents starvation of low-priority events through fair scheduling
|
|
385
|
+
- Distributed-safe: Uses database queries to track concurrency
|
|
386
|
+
|
|
387
|
+
**Use Cases:**
|
|
388
|
+
- Critical user notifications (high priority)
|
|
389
|
+
- Background cleanup jobs (low priority)
|
|
390
|
+
- Rate-limited API calls (maxConcurrency = 1)
|
|
391
|
+
- Resource-intensive tasks (maxConcurrency = 3)
|
|
392
|
+
|
|
393
|
+
### Bulk Scheduling API
|
|
394
|
+
|
|
395
|
+
Schedule thousands of events efficiently in a single operation.
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
// Prepare batch of events
|
|
399
|
+
const events = users.map(user => ({
|
|
400
|
+
eventTypeName: 'WELCOME_EMAIL',
|
|
401
|
+
payload: { userId: user.id, email: user.email },
|
|
402
|
+
scheduleType: ScheduleType.ONE_TIME,
|
|
403
|
+
scheduledAt: new Date(Date.now() + 3600000), // 1 hour from now
|
|
404
|
+
idempotencyKey: `welcome-${user.id}`, // Prevent duplicates
|
|
405
|
+
}));
|
|
406
|
+
|
|
407
|
+
// FAIL_ALL mode: Transaction-safe, rolls back if any event fails
|
|
408
|
+
const scheduled = await scheduler.scheduleEvents(events, { mode: 'FAIL_ALL' });
|
|
409
|
+
|
|
410
|
+
// PARTIAL_SUCCESS mode: Continues on errors
|
|
411
|
+
const scheduled = await scheduler.scheduleEvents(events, { mode: 'PARTIAL_SUCCESS' });
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Features:**
|
|
415
|
+
- **Transaction Support**: FAIL_ALL mode uses single transaction
|
|
416
|
+
- **Partial Success**: PARTIAL_SUCCESS mode processes valid events
|
|
417
|
+
- **Validation**: All inputs validated before processing
|
|
418
|
+
- **Idempotency**: Detects duplicate idempotency keys in batch
|
|
419
|
+
- **Performance**: Optimized for 1000+ events
|
|
420
|
+
|
|
421
|
+
**Options:**
|
|
422
|
+
- `mode: 'FAIL_ALL'` (default): All-or-nothing transaction
|
|
423
|
+
- `mode: 'PARTIAL_SUCCESS'`: Returns successful events, logs failures
|
|
424
|
+
|
|
425
|
+
**Use Cases:**
|
|
426
|
+
- Onboarding campaigns (bulk welcome emails)
|
|
427
|
+
- Batch reporting jobs
|
|
428
|
+
- Mass reminders/notifications
|
|
429
|
+
- Data migration scheduling
|
|
430
|
+
|
|
431
|
+
### Middleware System
|
|
432
|
+
|
|
433
|
+
Inject custom logic into the event execution pipeline.
|
|
434
|
+
|
|
435
|
+
**Register Middleware:**
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
// Logging middleware
|
|
439
|
+
scheduler.use(async (ctx, next) => {
|
|
440
|
+
console.log(`[START] ${ctx.eventType} - ${ctx.eventId}`);
|
|
441
|
+
const start = Date.now();
|
|
442
|
+
|
|
443
|
+
await next(); // Call next middleware or handler
|
|
444
|
+
|
|
445
|
+
const duration = Date.now() - start;
|
|
446
|
+
console.log(`[END] ${ctx.eventType} - ${duration}ms`);
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
// Tracing middleware (e.g., OpenTelemetry)
|
|
450
|
+
scheduler.use(async (ctx, next) => {
|
|
451
|
+
const span = tracer.startSpan(ctx.eventType, {
|
|
452
|
+
attributes: {
|
|
453
|
+
'event.id': ctx.eventId,
|
|
454
|
+
'event.type': ctx.eventType,
|
|
455
|
+
'event.attempt': ctx.attemptNumber,
|
|
456
|
+
'event.correlation_id': ctx.correlationId,
|
|
457
|
+
},
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
try {
|
|
461
|
+
await next();
|
|
462
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
463
|
+
} catch (error) {
|
|
464
|
+
span.recordException(error);
|
|
465
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
466
|
+
throw error;
|
|
467
|
+
} finally {
|
|
468
|
+
span.end();
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Authentication/authorization middleware
|
|
473
|
+
scheduler.use(async (ctx, next) => {
|
|
474
|
+
if (ctx.payload.requiresAuth) {
|
|
475
|
+
await validateAuthToken(ctx.payload.token);
|
|
476
|
+
}
|
|
477
|
+
await next();
|
|
478
|
+
});
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**Middleware Context:**
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
interface MiddlewareContext {
|
|
485
|
+
eventId: string; // Unique event instance ID
|
|
486
|
+
eventType: string; // Event type name
|
|
487
|
+
payload: Record<string, any>; // Event payload
|
|
488
|
+
attemptNumber: number; // Current execution attempt
|
|
489
|
+
correlationId: string; // Correlation ID for tracing
|
|
490
|
+
scheduledAt: Date; // Original scheduled time
|
|
491
|
+
startedAt: Date; // Execution start time
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Class-based Middleware:**
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
class MetricsMiddleware implements IMiddleware {
|
|
499
|
+
async use(ctx: MiddlewareContext, next: NextFunction) {
|
|
500
|
+
metrics.increment('events.started', { type: ctx.eventType });
|
|
501
|
+
|
|
502
|
+
try {
|
|
503
|
+
await next();
|
|
504
|
+
metrics.increment('events.succeeded', { type: ctx.eventType });
|
|
505
|
+
} catch (error) {
|
|
506
|
+
metrics.increment('events.failed', { type: ctx.eventType });
|
|
507
|
+
throw error;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
scheduler.use(new MetricsMiddleware());
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
**Features:**
|
|
516
|
+
- **Execution Order**: Middleware executes in registration order
|
|
517
|
+
- **Pre/Post Processing**: Code before `next()` runs first, code after runs last
|
|
518
|
+
- **Error Propagation**: Errors bubble up through middleware chain
|
|
519
|
+
- **Async Support**: Full async/await support
|
|
520
|
+
- **No Breaking Changes**: Existing handlers work unchanged
|
|
521
|
+
|
|
522
|
+
**Use Cases:**
|
|
523
|
+
- Distributed tracing (OpenTelemetry, Jaeger)
|
|
524
|
+
- Performance monitoring (execution times)
|
|
525
|
+
- Payload validation/transformation
|
|
526
|
+
- Authentication/authorization
|
|
527
|
+
- Custom logging and audit trails
|
|
528
|
+
- Analytics and metrics collection
|
|
529
|
+
|
|
313
530
|
## Production Features
|
|
314
531
|
|
|
315
532
|
### Error Handling
|
|
@@ -695,6 +912,12 @@ The package creates the following tables:
|
|
|
695
912
|
|
|
696
913
|
All tables support an optional prefix via `tablePrefix` config option.
|
|
697
914
|
|
|
915
|
+
Persistence note:
|
|
916
|
+
|
|
917
|
+
- All scheduler state (event types, event instances, execution history, dead letters) is persisted to your database via the `IDatabaseAdapter` you provide. The package does not create or manage database connections itself — consumers must supply an adapter implementation (see `src/interfaces/database-adapter.interface.ts`) that performs `query` and `transaction` operations against their chosen database client. This ensures scheduled jobs survive process restarts and can be safely scaled across multiple instances: locks, idempotency keys, and database transactions provide distributed-safety for scheduling operations.
|
|
918
|
+
|
|
919
|
+
Be sure to run the shipped migrations and set `tablePrefix` if you want to namespace tables in a shared schema.
|
|
920
|
+
|
|
698
921
|
## What's New in v2.0.0
|
|
699
922
|
|
|
700
923
|
Version 2.0.0 brings production-grade features and comprehensive testing:
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const DEFAULTS: {
|
|
2
|
+
POLLING_INTERVAL_MS: number;
|
|
3
|
+
LOCK_DURATION_MS: number;
|
|
4
|
+
BATCH_SIZE: number;
|
|
5
|
+
MAX_BATCH_SIZE: number;
|
|
6
|
+
CONCURRENCY: number;
|
|
7
|
+
HANDLER_TIMEOUT_MS: number;
|
|
8
|
+
GRACE_PERIOD_MS: number;
|
|
9
|
+
RRULE_MAX_COMPUTATION_ATTEMPTS: number;
|
|
10
|
+
RRULE_MAX_OCCURRENCES: number;
|
|
11
|
+
RRULE_MAX_COMPUTATION_TIME_MS: number;
|
|
12
|
+
RRULE_MAX_FUTURE_YEARS: number;
|
|
13
|
+
MAX_PAYLOAD_DEPTH: number;
|
|
14
|
+
MAX_PAYLOAD_PREVIEW_CHARS: number;
|
|
15
|
+
MAX_PAYLOAD_SIZE_BYTES: number;
|
|
16
|
+
SQS_MAX_PAYLOAD_BYTES: number;
|
|
17
|
+
RETRY_BASE_DELAY_MS: number;
|
|
18
|
+
RETRY_MAX_DELAY_MS: number;
|
|
19
|
+
CIRCUIT_BREAKER_RESET_MS: number;
|
|
20
|
+
CIRCUIT_BREAKER_TIMEOUT_MS: number;
|
|
21
|
+
MAX_FUTURE_DATE: Date;
|
|
22
|
+
MIN_PAST_DATE: Date;
|
|
23
|
+
INTERVAL_MAX: number;
|
|
24
|
+
COUNT_MAX: number;
|
|
25
|
+
RETRY_DELAY_MAX_MS: number;
|
|
26
|
+
EVENT_TYPE_NAME_MAX_LENGTH: number;
|
|
27
|
+
IDEMPOTENCY_KEY_MAX_LENGTH: number;
|
|
28
|
+
};
|
|
29
|
+
export default DEFAULTS;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULTS = void 0;
|
|
4
|
+
exports.DEFAULTS = {
|
|
5
|
+
POLLING_INTERVAL_MS: 5000,
|
|
6
|
+
LOCK_DURATION_MS: 30000,
|
|
7
|
+
BATCH_SIZE: 50,
|
|
8
|
+
MAX_BATCH_SIZE: 1000,
|
|
9
|
+
CONCURRENCY: 10,
|
|
10
|
+
HANDLER_TIMEOUT_MS: 300000,
|
|
11
|
+
GRACE_PERIOD_MS: 30000,
|
|
12
|
+
RRULE_MAX_COMPUTATION_ATTEMPTS: 10,
|
|
13
|
+
RRULE_MAX_OCCURRENCES: 1000,
|
|
14
|
+
RRULE_MAX_COMPUTATION_TIME_MS: 5000,
|
|
15
|
+
RRULE_MAX_FUTURE_YEARS: 100,
|
|
16
|
+
MAX_PAYLOAD_DEPTH: 10,
|
|
17
|
+
MAX_PAYLOAD_PREVIEW_CHARS: 100,
|
|
18
|
+
MAX_PAYLOAD_SIZE_BYTES: 2 * 1024 * 1024,
|
|
19
|
+
SQS_MAX_PAYLOAD_BYTES: 256 * 1024,
|
|
20
|
+
RETRY_BASE_DELAY_MS: 1000,
|
|
21
|
+
RETRY_MAX_DELAY_MS: 5 * 60 * 1000,
|
|
22
|
+
CIRCUIT_BREAKER_RESET_MS: 30000,
|
|
23
|
+
CIRCUIT_BREAKER_TIMEOUT_MS: 60000,
|
|
24
|
+
MAX_FUTURE_DATE: new Date('2099-12-31T23:59:59.999Z'),
|
|
25
|
+
MIN_PAST_DATE: new Date('2000-01-01T00:00:00.000Z'),
|
|
26
|
+
INTERVAL_MAX: 1000,
|
|
27
|
+
COUNT_MAX: 100000,
|
|
28
|
+
RETRY_DELAY_MAX_MS: 24 * 60 * 60 * 1000,
|
|
29
|
+
EVENT_TYPE_NAME_MAX_LENGTH: 255,
|
|
30
|
+
IDEMPOTENCY_KEY_MAX_LENGTH: 255,
|
|
31
|
+
};
|
|
32
|
+
exports.default = exports.DEFAULTS;
|
|
33
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAIa,QAAA,QAAQ,GAAG;IAEtB,mBAAmB,EAAE,IAAI;IACzB,gBAAgB,EAAE,KAAK;IACvB,UAAU,EAAE,EAAE;IACd,cAAc,EAAE,IAAI;IACpB,WAAW,EAAE,EAAE;IAGf,kBAAkB,EAAE,MAAM;IAG1B,eAAe,EAAE,KAAK;IAGtB,8BAA8B,EAAE,EAAE;IAClC,qBAAqB,EAAE,IAAI;IAC3B,6BAA6B,EAAE,IAAI;IACnC,sBAAsB,EAAE,GAAG;IAG3B,iBAAiB,EAAE,EAAE;IACrB,yBAAyB,EAAE,GAAG;IAC9B,sBAAsB,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IACvC,qBAAqB,EAAE,GAAG,GAAG,IAAI;IAGjC,mBAAmB,EAAE,IAAI;IACzB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;IAGjC,wBAAwB,EAAE,KAAK;IAC/B,0BAA0B,EAAE,KAAK;IAGjC,eAAe,EAAE,IAAI,IAAI,CAAC,0BAA0B,CAAC;IACrD,aAAa,EAAE,IAAI,IAAI,CAAC,0BAA0B,CAAC;IACnD,YAAY,EAAE,IAAI;IAClB,SAAS,EAAE,MAAM;IACjB,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;IAGvC,0BAA0B,EAAE,GAAG;IAC/B,0BAA0B,EAAE,GAAG;CAChC,CAAC;AAEF,kBAAe,gBAAQ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const CRON_METADATA = "scheduler:cron";
|
|
2
|
+
export interface CronOptions {
|
|
3
|
+
name?: string;
|
|
4
|
+
timezone?: string;
|
|
5
|
+
payload?: Record<string, any>;
|
|
6
|
+
startDate?: Date;
|
|
7
|
+
endDate?: Date;
|
|
8
|
+
enabled?: boolean;
|
|
9
|
+
recoverMissedExecutions?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function Cron(expression: string, options?: CronOptions): MethodDecorator;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CRON_METADATA = void 0;
|
|
4
|
+
exports.Cron = Cron;
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
exports.CRON_METADATA = 'scheduler:cron';
|
|
7
|
+
function Cron(expression, options = {}) {
|
|
8
|
+
return (target, propertyKey, descriptor) => {
|
|
9
|
+
(0, common_1.SetMetadata)(exports.CRON_METADATA, { expression, options })(descriptor.value);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=cron.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.decorator.js","sourceRoot":"","sources":["../../src/decorators/cron.decorator.ts"],"names":[],"mappings":";;;AAcA,oBAIC;AAlBD,2CAA6C;AAEhC,QAAA,aAAa,GAAG,gBAAgB,CAAC;AAY9C,SAAgB,IAAI,CAAC,UAAkB,EAAE,UAAuB,EAAE;IAChE,OAAO,CAAC,MAAW,EAAE,WAA4B,EAAE,UAA8B,EAAE,EAAE;QACnF,IAAA,oBAAW,EAAC,qBAAa,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,9 +6,10 @@ export type { IQueueAdapter, QueueMessage, } from './interfaces/queue-adapter.in
|
|
|
6
6
|
export type { ILoggerAdapter } from './interfaces/logger-adapter.interface';
|
|
7
7
|
export type { ICacheAdapter } from './interfaces/cache-adapter.interface';
|
|
8
8
|
export type { IEventHandler, HandlerResult, ExecutionContext, } from './interfaces/event-handler.interface';
|
|
9
|
+
export type { MiddlewareContext, MiddlewareFunction, NextFunction, IMiddleware, } from './interfaces/middleware.interface';
|
|
9
10
|
export type { SchedulerConfig, SchedulerHooks, SchedulerModuleOptions, SchedulerModuleAsyncOptions, AdapterProvider, } from './interfaces/config.interface';
|
|
10
11
|
export { EventStatus, ScheduleType, RetryBackoff, ExecutionStatus, } from './types/enums';
|
|
11
|
-
export type { RetryPolicy, CreateEventTypeInput, ScheduleEventInput, EventFilters, PaginatedResult, } from './types/inputs';
|
|
12
|
+
export type { RetryPolicy, CreateEventTypeInput, ScheduleEventInput, BulkScheduleOptions, EventFilters, PaginatedResult, } from './types/inputs';
|
|
12
13
|
export { EventType } from './models/event-type.model';
|
|
13
14
|
export { EventInstance } from './models/event-instance.model';
|
|
14
15
|
export { EventExecution } from './models/event-execution.model';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AAGxB,kEAAgE;AAAvD,qHAAA,gBAAgB,OAAA;AAGzB,gFAAoE;AAA3D,uHAAA,YAAY,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AAGxB,kEAAgE;AAAvD,qHAAA,gBAAgB,OAAA;AAGzB,gFAAoE;AAA3D,uHAAA,YAAY,OAAA;AAuCrB,uCAKuB;AAJrB,oGAAA,WAAW,OAAA;AACX,qGAAA,YAAY,OAAA;AACZ,qGAAA,YAAY,OAAA;AACZ,wGAAA,eAAe,OAAA;AAajB,8DAAsD;AAA7C,6GAAA,SAAS,OAAA;AAClB,sEAA8D;AAArD,qHAAA,aAAa,OAAA;AACtB,wEAAgE;AAAvD,uHAAA,cAAc,OAAA;AACvB,gEAAwD;AAA/C,+GAAA,UAAU,OAAA;AAGnB,2CAA0E;AAAjE,2GAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface MiddlewareContext {
|
|
2
|
+
eventId: string;
|
|
3
|
+
eventType: string;
|
|
4
|
+
payload: Record<string, any>;
|
|
5
|
+
attemptNumber: number;
|
|
6
|
+
correlationId: string;
|
|
7
|
+
scheduledAt: Date;
|
|
8
|
+
startedAt: Date;
|
|
9
|
+
}
|
|
10
|
+
export type NextFunction = () => Promise<void>;
|
|
11
|
+
export type MiddlewareFunction = (ctx: MiddlewareContext, next: NextFunction) => Promise<void>;
|
|
12
|
+
export interface IMiddleware {
|
|
13
|
+
use(ctx: MiddlewareContext, next: NextFunction): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.interface.js","sourceRoot":"","sources":["../../src/interfaces/middleware.interface.ts"],"names":[],"mappings":""}
|
package/dist/migrations/index.js
CHANGED
|
@@ -40,6 +40,8 @@ CREATE TABLE IF NOT EXISTS ${prefix}event_types (
|
|
|
40
40
|
retry_max INTEGER DEFAULT 3,
|
|
41
41
|
retry_delay_ms INTEGER DEFAULT 5000,
|
|
42
42
|
retry_backoff VARCHAR(20) DEFAULT 'exponential',
|
|
43
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
44
|
+
max_concurrency INTEGER DEFAULT NULL,
|
|
43
45
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
44
46
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
45
47
|
);
|
|
@@ -128,6 +130,10 @@ CREATE INDEX IF NOT EXISTS idx_${prefix}dead_letters_instance
|
|
|
128
130
|
-- Index for status queries
|
|
129
131
|
CREATE INDEX IF NOT EXISTS idx_${prefix}event_instances_status
|
|
130
132
|
ON ${prefix}event_instances (status);
|
|
133
|
+
|
|
134
|
+
-- Index for priority ordering
|
|
135
|
+
CREATE INDEX IF NOT EXISTS idx_${prefix}event_types_priority
|
|
136
|
+
ON ${prefix}event_types (priority DESC);
|
|
131
137
|
`.trim();
|
|
132
138
|
}
|
|
133
139
|
function getCreateIndexesDown(prefix) {
|
|
@@ -137,6 +143,7 @@ DROP INDEX IF EXISTS idx_${prefix}event_instances_type;
|
|
|
137
143
|
DROP INDEX IF EXISTS idx_${prefix}event_executions_instance;
|
|
138
144
|
DROP INDEX IF EXISTS idx_${prefix}dead_letters_instance;
|
|
139
145
|
DROP INDEX IF EXISTS idx_${prefix}event_instances_status;
|
|
146
|
+
DROP INDEX IF EXISTS idx_${prefix}event_types_priority;
|
|
140
147
|
`.trim();
|
|
141
148
|
}
|
|
142
149
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":";;AAmBA,sCA8BC;AA9BD,SAAgB,aAAa,CAAC,UAA4B,EAAE;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IAEzC,OAAO;QACL;YACE,OAAO,EAAE,wBAAwB;YACjC,EAAE,EAAE,qBAAqB,CAAC,MAAM,CAAC;YACjC,IAAI,EAAE,uBAAuB,CAAC,MAAM,CAAC;SACtC;QACD;YACE,OAAO,EAAE,4BAA4B;YACrC,EAAE,EAAE,yBAAyB,CAAC,MAAM,CAAC;YACrC,IAAI,EAAE,2BAA2B,CAAC,MAAM,CAAC;SAC1C;QACD;YACE,OAAO,EAAE,6BAA6B;YACtC,EAAE,EAAE,0BAA0B,CAAC,MAAM,CAAC;YACtC,IAAI,EAAE,4BAA4B,CAAC,MAAM,CAAC;SAC3C;QACD;YACE,OAAO,EAAE,yBAAyB;YAClC,EAAE,EAAE,sBAAsB,CAAC,MAAM,CAAC;YAClC,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC;SACvC;QACD;YACE,OAAO,EAAE,oBAAoB;YAC7B,EAAE,EAAE,kBAAkB,CAAC,MAAM,CAAC;YAC9B,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC;SACnC;KACF,CAAC;AACJ,CAAC;AAGD,SAAS,qBAAqB,CAAC,MAAc;IAC3C,OAAO;6BACoB,MAAM
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":";;AAmBA,sCA8BC;AA9BD,SAAgB,aAAa,CAAC,UAA4B,EAAE;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IAEzC,OAAO;QACL;YACE,OAAO,EAAE,wBAAwB;YACjC,EAAE,EAAE,qBAAqB,CAAC,MAAM,CAAC;YACjC,IAAI,EAAE,uBAAuB,CAAC,MAAM,CAAC;SACtC;QACD;YACE,OAAO,EAAE,4BAA4B;YACrC,EAAE,EAAE,yBAAyB,CAAC,MAAM,CAAC;YACrC,IAAI,EAAE,2BAA2B,CAAC,MAAM,CAAC;SAC1C;QACD;YACE,OAAO,EAAE,6BAA6B;YACtC,EAAE,EAAE,0BAA0B,CAAC,MAAM,CAAC;YACtC,IAAI,EAAE,4BAA4B,CAAC,MAAM,CAAC;SAC3C;QACD;YACE,OAAO,EAAE,yBAAyB;YAClC,EAAE,EAAE,sBAAsB,CAAC,MAAM,CAAC;YAClC,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC;SACvC;QACD;YACE,OAAO,EAAE,oBAAoB;YAC7B,EAAE,EAAE,kBAAkB,CAAC,MAAM,CAAC;YAC9B,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC;SACnC;KACF,CAAC;AACJ,CAAC;AAGD,SAAS,qBAAqB,CAAC,MAAc;IAC3C,OAAO;6BACoB,MAAM;;;;;;;;;;;;CAYlC,CAAC,IAAI,EAAE,CAAC;AACT,CAAC;AAED,SAAS,uBAAuB,CAAC,MAAc;IAC7C,OAAO,wBAAwB,MAAM,sBAAsB,CAAC;AAC9D,CAAC;AAGD,SAAS,yBAAyB,CAAC,MAAc;IAC/C,OAAO;6BACoB,MAAM;;2CAEQ,MAAM;;;;;;;;;;;;;;;;;CAiBhD,CAAC,IAAI,EAAE,CAAC;AACT,CAAC;AAED,SAAS,2BAA2B,CAAC,MAAc;IACjD,OAAO,wBAAwB,MAAM,0BAA0B,CAAC;AAClE,CAAC;AAGD,SAAS,0BAA0B,CAAC,MAAc;IAChD,OAAO;6BACoB,MAAM;;+CAEY,MAAM;;;;;;;;;CASpD,CAAC,IAAI,EAAE,CAAC;AACT,CAAC;AAED,SAAS,4BAA4B,CAAC,MAAc;IAClD,OAAO,wBAAwB,MAAM,2BAA2B,CAAC;AACnE,CAAC;AAGD,SAAS,sBAAsB,CAAC,MAAc;IAC5C,OAAO;6BACoB,MAAM;;+CAEY,MAAM;;;;;CAKpD,CAAC,IAAI,EAAE,CAAC;AACT,CAAC;AAED,SAAS,wBAAwB,CAAC,MAAc;IAC9C,OAAO,wBAAwB,MAAM,uBAAuB,CAAC;AAC/D,CAAC;AAGD,SAAS,kBAAkB,CAAC,MAAc;IACxC,OAAO;;iCAEwB,MAAM;OAChC,MAAM;;;;iCAIoB,MAAM;OAChC,MAAM;;;iCAGoB,MAAM;OAChC,MAAM;;;iCAGoB,MAAM;OAChC,MAAM;;;iCAGoB,MAAM;OAChC,MAAM;;;iCAGoB,MAAM;OAChC,MAAM;CACZ,CAAC,IAAI,EAAE,CAAC;AACT,CAAC;AAED,SAAS,oBAAoB,CAAC,MAAc;IAC1C,OAAO;2BACkB,MAAM;2BACN,MAAM;2BACN,MAAM;2BACN,MAAM;2BACN,MAAM;2BACN,MAAM;CAChC,CAAC,IAAI,EAAE,CAAC;AACT,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-type.model.js","sourceRoot":"","sources":["../../src/models/event-type.model.ts"],"names":[],"mappings":";;;AAMA,MAAa,SAAS;
|
|
1
|
+
{"version":3,"file":"event-type.model.js","sourceRoot":"","sources":["../../src/models/event-type.model.ts"],"names":[],"mappings":";;;AAMA,MAAa,SAAS;IAYpB,YAAY,IAAwB;QAClC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,WAAW;QACb,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,QAAQ;YACzB,OAAO,EAAE,IAAI,CAAC,YAAY;YAC1B,OAAO,EAAE,IAAI,CAAC,YAAY;SAC3B,CAAC;IACJ,CAAC;CACF;AAvBD,8BAuBC"}
|
package/dist/scheduler.module.js
CHANGED
|
@@ -11,16 +11,19 @@ exports.SchedulerModule = void 0;
|
|
|
11
11
|
const common_1 = require("@nestjs/common");
|
|
12
12
|
const core_1 = require("@nestjs/core");
|
|
13
13
|
const console_logger_1 = require("./utils/console-logger");
|
|
14
|
+
const constants_1 = require("./constants");
|
|
14
15
|
const event_manager_service_1 = require("./services/event-manager.service");
|
|
15
16
|
const polling_engine_service_1 = require("./services/polling-engine.service");
|
|
16
17
|
const dispatcher_service_1 = require("./services/dispatcher.service");
|
|
18
|
+
const concurrency_manager_service_1 = require("./services/concurrency-manager.service");
|
|
19
|
+
const cron_discovery_service_1 = require("./services/cron-discovery.service");
|
|
17
20
|
const scheduler_service_1 = require("./services/scheduler.service");
|
|
18
21
|
const handler_registry_1 = require("./registry/handler.registry");
|
|
19
22
|
const DEFAULT_CONFIG = {
|
|
20
|
-
pollingIntervalMs:
|
|
21
|
-
lockDurationMs:
|
|
22
|
-
batchSize:
|
|
23
|
-
concurrency:
|
|
23
|
+
pollingIntervalMs: constants_1.DEFAULTS.POLLING_INTERVAL_MS,
|
|
24
|
+
lockDurationMs: constants_1.DEFAULTS.LOCK_DURATION_MS,
|
|
25
|
+
batchSize: constants_1.DEFAULTS.BATCH_SIZE,
|
|
26
|
+
concurrency: constants_1.DEFAULTS.CONCURRENCY,
|
|
24
27
|
deadLetterEnabled: true,
|
|
25
28
|
tablePrefix: '',
|
|
26
29
|
workerMode: true,
|
|
@@ -33,7 +36,7 @@ let SchedulerModule = SchedulerModule_1 = class SchedulerModule {
|
|
|
33
36
|
module: SchedulerModule_1,
|
|
34
37
|
imports: [core_1.DiscoveryModule],
|
|
35
38
|
providers,
|
|
36
|
-
exports: [scheduler_service_1.SchedulerService, event_manager_service_1.EventManager, handler_registry_1.HandlerRegistry],
|
|
39
|
+
exports: [scheduler_service_1.SchedulerService, event_manager_service_1.EventManager, dispatcher_service_1.Dispatcher, handler_registry_1.HandlerRegistry],
|
|
37
40
|
};
|
|
38
41
|
}
|
|
39
42
|
static forRootAsync(options) {
|
|
@@ -42,7 +45,7 @@ let SchedulerModule = SchedulerModule_1 = class SchedulerModule {
|
|
|
42
45
|
module: SchedulerModule_1,
|
|
43
46
|
imports: [...(options.imports || []), core_1.DiscoveryModule],
|
|
44
47
|
providers,
|
|
45
|
-
exports: [scheduler_service_1.SchedulerService, event_manager_service_1.EventManager, handler_registry_1.HandlerRegistry],
|
|
48
|
+
exports: [scheduler_service_1.SchedulerService, event_manager_service_1.EventManager, dispatcher_service_1.Dispatcher, handler_registry_1.HandlerRegistry],
|
|
46
49
|
};
|
|
47
50
|
}
|
|
48
51
|
static createProviders(options) {
|
|
@@ -76,7 +79,9 @@ let SchedulerModule = SchedulerModule_1 = class SchedulerModule {
|
|
|
76
79
|
? [this.createAdapterProvider('CACHE_ADAPTER', options.cache)]
|
|
77
80
|
: []),
|
|
78
81
|
handler_registry_1.HandlerRegistry,
|
|
82
|
+
cron_discovery_service_1.CronDiscovery,
|
|
79
83
|
event_manager_service_1.EventManager,
|
|
84
|
+
concurrency_manager_service_1.ConcurrencyManager,
|
|
80
85
|
polling_engine_service_1.PollingEngine,
|
|
81
86
|
dispatcher_service_1.Dispatcher,
|
|
82
87
|
scheduler_service_1.SchedulerService,
|
|
@@ -132,7 +137,9 @@ let SchedulerModule = SchedulerModule_1 = class SchedulerModule {
|
|
|
132
137
|
inject: ['SCHEDULER_OPTIONS'],
|
|
133
138
|
},
|
|
134
139
|
handler_registry_1.HandlerRegistry,
|
|
140
|
+
cron_discovery_service_1.CronDiscovery,
|
|
135
141
|
event_manager_service_1.EventManager,
|
|
142
|
+
concurrency_manager_service_1.ConcurrencyManager,
|
|
136
143
|
polling_engine_service_1.PollingEngine,
|
|
137
144
|
dispatcher_service_1.Dispatcher,
|
|
138
145
|
scheduler_service_1.SchedulerService,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.module.js","sourceRoot":"","sources":["../src/scheduler.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAyE;AACzE,uCAA+C;AAW/C,2DAAuD;AACvD,4EAAgE;AAChE,8EAAkE;AAClE,sEAA2D;AAC3D,oEAAgE;AAChE,kEAA8D;AAK9D,MAAM,cAAc,GAAoB;IACtC,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"scheduler.module.js","sourceRoot":"","sources":["../src/scheduler.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IDatabaseAdapter } from '../interfaces/database-adapter.interface';
|
|
2
|
+
import { ILoggerAdapter } from '../interfaces/logger-adapter.interface';
|
|
3
|
+
export declare class ConcurrencyManager {
|
|
4
|
+
private readonly db;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private readonly tablePrefix;
|
|
7
|
+
constructor(db: IDatabaseAdapter, logger: ILoggerAdapter, tablePrefix: string);
|
|
8
|
+
getCurrentExecutingCount(eventTypeId: string): Promise<number>;
|
|
9
|
+
canExecute(eventTypeId: string, maxConcurrency: number | null): Promise<boolean>;
|
|
10
|
+
getBulkExecutingCounts(eventTypeIds: string[]): Promise<Map<string, number>>;
|
|
11
|
+
}
|