echoapi-cron-scheduler-batch 1.0.17 → 1.0.20

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.
Files changed (2) hide show
  1. package/index.js +46 -3
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -137,11 +137,13 @@ class CronScheduler {
137
137
  try { if (fs.existsSync(lockFile)) fs.unlinkSync(lockFile); } catch (e) { }
138
138
  }
139
139
 
140
- _dispatch(job) {
140
+ _dispatch(job, skipLock = false) {
141
141
  console.log(`🎯 [Master] 准备分发: ${job.job_id} (${job.name || 'Task'})`);
142
- if (!this._tryAcquireLock(job.job_id)) {
142
+
143
+ // 如果不跳过锁检查,且抢锁失败,则退出
144
+ if (!skipLock && !this._tryAcquireLock(job.job_id)) {
143
145
  console.warn(`🔒 [Lock] 抢锁失败,跳过执行: ${job.job_id}`);
144
- return;
146
+ return false; // 返回 false 表示未成功分发
145
147
  }
146
148
 
147
149
  try {
@@ -167,6 +169,7 @@ class CronScheduler {
167
169
  console.error(`💥 [Master] 分发崩溃:`, e.message);
168
170
  this._releaseLock(job.job_id);
169
171
  }
172
+ return true;
170
173
  }
171
174
 
172
175
  // ==========================================
@@ -276,6 +279,46 @@ class CronScheduler {
276
279
  }
277
280
  }
278
281
 
282
+ /**
283
+ * 🚀 立即手动执行指定任务
284
+ * @param {string} job_id 任务ID
285
+ */
286
+ async triggerJobNow(job_id) {
287
+ console.log(`⚡ [Manual] 收到立即执行指令: ${job_id}`);
288
+
289
+ // 1. 只有主进程负责分发
290
+ if (!cluster.isPrimary) {
291
+ console.warn(`⚠️ [Manual] 非主进程,跳过手动触发`);
292
+ return { success: false, message: 'Only Primary process can trigger jobs.' };
293
+ }
294
+
295
+ const jobPath = path.join(this.paths.jobs, `${job_id}.json`);
296
+
297
+ // 2. 检查任务是否存在
298
+ if (!fs.existsSync(jobPath)) {
299
+ console.error(`❌ [Manual] 触发失败:任务文件不存在 ${job_id}`);
300
+ return { success: false, message: 'Job not found.' };
301
+ }
302
+
303
+ try {
304
+ // 3. 读取最新的任务内容
305
+ const job = JSON.parse(fs.readFileSync(jobPath, 'utf8'));
306
+
307
+ // 4. 执行分发逻辑
308
+ // 注意:这里会进入 _dispatch,内部会尝试 _tryAcquireLock
309
+ // 关键改动:传入 true 强制执行,或者根据返回值判断
310
+ const dispatched = this._dispatch(job, true);
311
+
312
+ if (dispatched) {
313
+ return { success: true, message: 'Job triggered successfully.' };
314
+ } else {
315
+ return { success: false, message: 'Job is already running on another node.' };
316
+ }
317
+ } catch (e) {
318
+ console.error(`💥 [Manual] 触发崩溃:`, e.message);
319
+ return { success: false, message: e.message };
320
+ }
321
+ }
279
322
  // ==========================================
280
323
  // 上报与 Worker 执行
281
324
  // ==========================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "echoapi-cron-scheduler-batch",
3
- "version": "1.0.17",
3
+ "version": "1.0.20",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {