koatty_schedule 3.3.2 → 3.3.3

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 CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [3.3.3](https://github.com/thinkkoa/koatty_schedule/compare/v3.3.2...v3.3.3) (2025-10-31)
6
+
5
7
  ### [3.3.2](https://github.com/thinkkoa/koatty_schedule/compare/v3.3.1...v3.3.2) (2025-06-22)
6
8
 
7
9
  ### [3.3.1](https://github.com/thinkkoa/koatty_schedule/compare/v3.3.0...v3.3.1) (2025-06-22)
package/README.md CHANGED
@@ -11,12 +11,15 @@ Powerful scheduled tasks and distributed locking solution for Koatty framework.
11
11
  - 🕒 **Flexible Scheduling**: Support for cron expressions with timezone configuration
12
12
  - 🔐 **Distributed Locking**: RedLock-based distributed locks with auto-extension
13
13
  - 🏗️ **Plugin Architecture**: Native Koatty plugin integration
14
- - ⚡ **Performance Optimized**: Singleton pattern, caching, and batch processing
15
- - 🛡️ **Enhanced Safety**: Lock renewal logic with timeout protection
14
+ - ⚡ **Performance Optimized**: Singleton pattern, caching, and memory-leak-free design
15
+ - 🛡️ **Enhanced Safety**: Lock renewal logic with timeout protection and automatic cleanup
16
16
  - 🌍 **Timezone Smart**: Three-tier priority system for timezone configuration
17
17
  - 📊 **Health Monitoring**: Built-in health checks and detailed status reporting
18
18
  - 🔧 **Easy Configuration**: Method-level and global configuration options
19
19
  - 🚀 **Smart Initialization**: Unified initialization timing for optimal dependency resolution
20
+ - 🎯 **Advanced Validation**: Comprehensive cron expression validation with bilingual error messages
21
+ - 🔌 **Redis Multi-Mode**: Support for Standalone, Sentinel, and Cluster Redis deployments
22
+ - 🧩 **Extensible Architecture**: Abstract interfaces for easy customization and extension
20
23
 
21
24
  ## Installation
22
25
 
@@ -53,6 +56,8 @@ export class Scheduled implements IPlugin {
53
56
  Update `src/config/plugin.ts`:
54
57
 
55
58
  ```typescript
59
+ import { RedisMode } from "koatty_schedule";
60
+
56
61
  export default {
57
62
  list: ["Scheduled"], // Plugin loading order
58
63
  config: {
@@ -62,6 +67,7 @@ export default {
62
67
  maxRetries: 3,
63
68
  retryDelayMs: 200,
64
69
  redisConfig: {
70
+ mode: RedisMode.STANDALONE, // or SENTINEL, CLUSTER
65
71
  host: "127.0.0.1",
66
72
  port: 6379,
67
73
  db: 0,
@@ -119,11 +125,96 @@ export class CriticalTaskService {
119
125
 
120
126
  ## Advanced Configuration
121
127
 
128
+ ### Redis Deployment Modes
129
+
130
+ koatty_schedule supports three Redis deployment modes:
131
+
132
+ #### Standalone Mode (Default)
133
+
134
+ ```typescript
135
+ import { RedisMode } from "koatty_schedule";
136
+
137
+ export default {
138
+ list: ["Scheduled"],
139
+ config: {
140
+ Scheduled: {
141
+ redisConfig: {
142
+ mode: RedisMode.STANDALONE, // or omit for default
143
+ host: "127.0.0.1",
144
+ port: 6379,
145
+ password: "your-password",
146
+ db: 0,
147
+ keyPrefix: "koatty:schedule:"
148
+ }
149
+ }
150
+ }
151
+ };
152
+ ```
153
+
154
+ #### Sentinel Mode (High Availability)
155
+
156
+ ```typescript
157
+ import { RedisMode } from "koatty_schedule";
158
+
159
+ export default {
160
+ list: ["Scheduled"],
161
+ config: {
162
+ Scheduled: {
163
+ redisConfig: {
164
+ mode: RedisMode.SENTINEL,
165
+ sentinels: [
166
+ { host: "192.168.1.10", port: 26379 },
167
+ { host: "192.168.1.11", port: 26379 },
168
+ { host: "192.168.1.12", port: 26379 }
169
+ ],
170
+ name: "mymaster", // Sentinel master name
171
+ password: "your-password",
172
+ sentinelPassword: "sentinel-password", // Optional
173
+ db: 0,
174
+ keyPrefix: "koatty:schedule:"
175
+ }
176
+ }
177
+ }
178
+ };
179
+ ```
180
+
181
+ #### Cluster Mode (Horizontal Scaling)
182
+
183
+ ```typescript
184
+ import { RedisMode } from "koatty_schedule";
185
+
186
+ export default {
187
+ list: ["Scheduled"],
188
+ config: {
189
+ Scheduled: {
190
+ redisConfig: {
191
+ mode: RedisMode.CLUSTER,
192
+ nodes: [
193
+ { host: "192.168.1.10", port: 7000 },
194
+ { host: "192.168.1.11", port: 7001 },
195
+ { host: "192.168.1.12", port: 7002 },
196
+ { host: "192.168.1.13", port: 7003 },
197
+ { host: "192.168.1.14", port: 7004 },
198
+ { host: "192.168.1.15", port: 7005 }
199
+ ],
200
+ redisOptions: {
201
+ password: "your-password",
202
+ db: 0
203
+ },
204
+ keyPrefix: "koatty:schedule:"
205
+ }
206
+ }
207
+ }
208
+ };
209
+ ```
210
+
122
211
  ### Global Plugin Configuration
123
212
 
124
213
  Configure global settings in `src/config/plugin.ts`:
125
214
 
126
215
  ```typescript
216
+ import { RedisMode } from "koatty_schedule";
217
+
127
218
  export default {
128
219
  list: ["Scheduled"],
129
220
  config: {
@@ -139,6 +230,7 @@ export default {
139
230
 
140
231
  // Redis configuration for distributed locks
141
232
  redisConfig: {
233
+ mode: RedisMode.STANDALONE,
142
234
  host: "redis.example.com",
143
235
  port: 6379,
144
236
  password: "your-password",
@@ -324,6 +416,10 @@ export class LongRunningTaskService {
324
416
 
325
417
  ## Cron Expression Examples
326
418
 
419
+ koatty_schedule supports both 5-part and 6-part (with seconds) cron expressions with comprehensive validation:
420
+
421
+ ### Basic Examples
422
+
327
423
  ```typescript
328
424
  export class CronExamplesService {
329
425
 
@@ -347,6 +443,90 @@ export class CronExamplesService {
347
443
  }
348
444
  ```
349
445
 
446
+ ### Advanced Examples (NEW in v3.4.0)
447
+
448
+ ```typescript
449
+ export class AdvancedCronService {
450
+
451
+ // Step values - Every 2 hours during business hours
452
+ @Scheduled('0 0 9-17/2 * * 1-5')
453
+ async businessHoursTask() { }
454
+
455
+ // List values - Run at 9 AM, 12 PM, and 6 PM
456
+ @Scheduled('0 0 9,12,18 * * *')
457
+ async specificHoursTask() { }
458
+
459
+ // Month names - Run on first day of Q1 months
460
+ @Scheduled('0 0 0 1 JAN,FEB,MAR *')
461
+ async quarterlyTask() { }
462
+
463
+ // Weekday names - Weekend morning task
464
+ @Scheduled('0 0 10 * * SAT,SUN')
465
+ async weekendTask() { }
466
+
467
+ // Complex expression - Every 15 minutes during working hours on weekdays
468
+ @Scheduled('0 */15 9-17 * * MON-FRI')
469
+ async frequentBusinessTask() { }
470
+
471
+ // Range with step - Every 3 days
472
+ @Scheduled('0 0 0 */3 * *')
473
+ async everyThreeDaysTask() { }
474
+ }
475
+ ```
476
+
477
+ ### Cron Expression Format
478
+
479
+ **6-part format (with seconds):**
480
+ ```
481
+ ┌────────────── second (0-59)
482
+ │ ┌──────────── minute (0-59)
483
+ │ │ ┌────────── hour (0-23)
484
+ │ │ │ ┌──────── day of month (1-31)
485
+ │ │ │ │ ┌────── month (1-12 or JAN-DEC)
486
+ │ │ │ │ │ ┌──── day of week (0-7 or SUN-SAT, 0 and 7 are Sunday)
487
+ │ │ │ │ │ │
488
+ * * * * * *
489
+ ```
490
+
491
+ **5-part format (without seconds):**
492
+ ```
493
+ ┌──────────── minute (0-59)
494
+ │ ┌────────── hour (0-23)
495
+ │ │ ┌──────── day of month (1-31)
496
+ │ │ │ ┌────── month (1-12 or JAN-DEC)
497
+ │ │ │ │ ┌──── day of week (0-7 or SUN-SAT)
498
+ │ │ │ │ │
499
+ * * * * *
500
+ ```
501
+
502
+ ### Special Characters
503
+
504
+ - `*` - Any value
505
+ - `,` - Value list separator (e.g., `1,3,5`)
506
+ - `-` - Range of values (e.g., `1-5`)
507
+ - `/` - Step values (e.g., `*/15` or `0-30/5`)
508
+
509
+ ### Validation Features (NEW)
510
+
511
+ The enhanced validator will catch common errors:
512
+
513
+ ```typescript
514
+ // ❌ Invalid - seconds out of range
515
+ @Scheduled('60 0 0 * * *') // Error: 秒字段的值无效: 60,必须在 0-59 之间
516
+
517
+ // ❌ Invalid - hours out of range
518
+ @Scheduled('0 0 25 * * *') // Error: 小时字段的值无效: 25,必须在 0-23 之间
519
+
520
+ // ❌ Invalid - invalid step value
521
+ @Scheduled('0 */0 * * * *') // Error: 分钟字段的步长值无效: 0
522
+
523
+ // ❌ Invalid - range start > end
524
+ @Scheduled('0 0 17-9 * * *') // Error: 小时字段的范围无效: 17-9
525
+
526
+ // ✅ Valid - all checks passed
527
+ @Scheduled('0 */15 9-17 * * 1-5') // Every 15 minutes, 9-5, weekdays
528
+ ```
529
+
350
530
  ## Troubleshooting
351
531
 
352
532
  ### Common Issues
@@ -391,32 +571,92 @@ DEBUG=koatty_schedule* npm start
391
571
  ### Decorators
392
572
 
393
573
  #### `@Scheduled(cron: string, timezone?: string)`
394
- - `cron`: Cron expression (6-part format with seconds)
574
+ - `cron`: Cron expression (5 or 6-part format, with comprehensive validation)
395
575
  - `timezone`: Optional timezone override (defaults to 'Asia/Beijing')
396
576
  - **Processing**: Records metadata in IOC container, CronJob created at `appReady`
577
+ - **Validation**: Full validation of all cron fields with bilingual error messages
397
578
 
398
579
  #### `@RedLock(lockName?: string, options?: RedLockMethodOptions)`
399
580
  - `lockName`: Unique lock identifier (auto-generated if not provided)
400
581
  - `options`: Method-level lock configuration
582
+ - **Features**: Automatic lock renewal (up to 3 times), memory-leak-free implementation
401
583
 
402
584
  ### Configuration Types
403
585
 
404
586
  ```typescript
587
+ // Scheduled options with Redis mode support
405
588
  interface ScheduledOptions {
406
589
  timezone?: string;
407
590
  lockTimeOut?: number;
408
591
  maxRetries?: number;
409
592
  retryDelayMs?: number;
410
593
  clockDriftFactor?: number;
411
- redisConfig?: RedisConfig;
594
+ redisConfig?: RedisConfig; // Supports Standalone, Sentinel, Cluster
412
595
  }
413
596
 
597
+ // RedLock method-level options
414
598
  interface RedLockMethodOptions {
415
599
  lockTimeOut?: number;
416
600
  maxRetries?: number;
417
601
  retryDelayMs?: number;
418
602
  clockDriftFactor?: number;
419
603
  }
604
+
605
+ // Redis configuration (NEW in v3.4.0)
606
+ enum RedisMode {
607
+ STANDALONE = 'standalone',
608
+ SENTINEL = 'sentinel',
609
+ CLUSTER = 'cluster'
610
+ }
611
+
612
+ interface RedisStandaloneConfig {
613
+ mode?: RedisMode.STANDALONE;
614
+ host: string;
615
+ port: number;
616
+ password?: string;
617
+ db?: number;
618
+ keyPrefix?: string;
619
+ }
620
+
621
+ interface RedisSentinelConfig {
622
+ mode: RedisMode.SENTINEL;
623
+ sentinels: Array<{ host: string; port: number }>;
624
+ name: string; // Master name
625
+ password?: string;
626
+ sentinelPassword?: string;
627
+ db?: number;
628
+ keyPrefix?: string;
629
+ }
630
+
631
+ interface RedisClusterConfig {
632
+ mode: RedisMode.CLUSTER;
633
+ nodes: Array<{ host: string; port: number }>;
634
+ redisOptions?: {
635
+ password?: string;
636
+ db?: number;
637
+ };
638
+ keyPrefix?: string;
639
+ }
640
+ ```
641
+
642
+ ### Exported Interfaces (NEW in v3.4.0)
643
+
644
+ For advanced customization and extension:
645
+
646
+ ```typescript
647
+ import {
648
+ IDistributedLock, // Abstract distributed lock interface
649
+ IRedisClient, // Abstract Redis client interface
650
+ RedisFactory, // Redis client factory
651
+ RedisClientAdapter, // Redis client adapter
652
+ RedLocker // RedLock implementation
653
+ } from "koatty_schedule";
654
+
655
+ // Example: Custom health check
656
+ const redLocker = RedLocker.getInstance();
657
+ const health = await redLocker.healthCheck();
658
+ console.log(health.status); // 'healthy' | 'unhealthy'
659
+ console.log(health.details); // Detailed status information
420
660
  ```
421
661
 
422
662
  ## Version Compatibility
@@ -424,6 +664,59 @@ interface RedLockMethodOptions {
424
664
  - **Koatty**: >= 2.0.0
425
665
  - **Node.js**: >= 14.0.0
426
666
  - **Redis**: >= 3.0.0
667
+ - **Redis Sentinel**: >= 3.0.0 (for high availability)
668
+ - **Redis Cluster**: >= 3.0.0 (for horizontal scaling)
669
+
670
+ ## What's New in v3.4.0 🎉
671
+
672
+ ### 🐛 Bug Fixes
673
+
674
+ - **Fixed memory leak** in `timeoutPromise` - timers are now properly cleaned up
675
+ - **Improved initialization cleanup** - prevents state inconsistency on retry
676
+
677
+ ### ✨ New Features
678
+
679
+ - **Redis Multi-Mode Support**: Standalone, Sentinel, and Cluster modes
680
+ - **Enhanced Cron Validation**: Complete validation of all fields with bilingual error messages
681
+ - **Abstract Interfaces**: `IDistributedLock` and `IRedisClient` for extensibility
682
+ - **Redis Factory**: `RedisFactory` for flexible Redis client creation
683
+
684
+ ### 🚀 Improvements
685
+
686
+ - Memory-leak-free design for long-running applications
687
+ - Better error messages with Chinese and English support
688
+ - Comprehensive cron expression validation (steps, ranges, lists, month/weekday names)
689
+ - Health check now reports Redis mode information
690
+
691
+ ### 📖 Documentation
692
+
693
+ - Added `UPGRADE_GUIDE.md` with migration instructions
694
+ - Added `IMPROVEMENTS_SUMMARY.md` with technical details
695
+ - Enhanced README with Redis multi-mode examples
696
+
697
+ ## Migration from v3.3.x
698
+
699
+ Most code works without changes. To use new features:
700
+
701
+ ```typescript
702
+ // Optional: Explicitly set Redis mode (defaults to STANDALONE)
703
+ import { RedisMode } from "koatty_schedule";
704
+
705
+ redisConfig: {
706
+ mode: RedisMode.STANDALONE, // or SENTINEL, CLUSTER
707
+ // ... rest of config
708
+ }
709
+ ```
710
+
711
+ See [UPGRADE_GUIDE.md](UPGRADE_GUIDE.md) for details.
712
+
713
+ ## Performance & Stability
714
+
715
+ - ✅ **Memory Stable**: No leaks in long-running applications
716
+ - ✅ **Production Ready**: Used in production environments
717
+ - ✅ **Well Tested**: Comprehensive test coverage
718
+ - ✅ **High Availability**: Sentinel mode support
719
+ - ✅ **Scalable**: Cluster mode for horizontal scaling
427
720
 
428
721
  ## License
429
722
 
@@ -437,4 +730,10 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
437
730
 
438
731
  - 📚 [Documentation](https://koatty.js.org/)
439
732
  - 🐛 [Issues](https://github.com/koattyjs/koatty_schedule/issues)
440
- - 💬 [Discussions](https://github.com/koattyjs/koatty_schedule/discussions)
733
+ - 💬 [Discussions](https://github.com/koattyjs/koatty_schedule/discussions)
734
+ - 📖 [Upgrade Guide](UPGRADE_GUIDE.md)
735
+ - 📝 [Changelog](CHANGELOG.md)
736
+
737
+ ---
738
+
739
+ **Maintained with ❤️ by the Koatty Team**