@steedos-labs/plugin-workflow 3.0.61 → 3.0.63
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.
|
@@ -4391,8 +4391,17 @@ UUFlowManager.timeoutAutoSubmit = async function (ins_id) {
|
|
|
4391
4391
|
query._id = ins_id;
|
|
4392
4392
|
}
|
|
4393
4393
|
|
|
4394
|
+
const startTime = Date.now();
|
|
4395
|
+
console.log(`[timeout_auto_submit] Starting timeout check with query:`, JSON.stringify(query));
|
|
4396
|
+
|
|
4394
4397
|
const instances = await db.instances.find(query).toArray();
|
|
4395
4398
|
|
|
4399
|
+
console.log(`[timeout_auto_submit] Found ${instances.length} instance(s) matching timeout criteria`);
|
|
4400
|
+
if (instances.length > 0) {
|
|
4401
|
+
const instanceIds = instances.map(i => i._id).join(', ');
|
|
4402
|
+
console.log(`[timeout_auto_submit] Instance IDs: [${instanceIds}]`);
|
|
4403
|
+
}
|
|
4404
|
+
|
|
4396
4405
|
for (const ins of instances) {
|
|
4397
4406
|
try {
|
|
4398
4407
|
const flow_id = ins.flow;
|
|
@@ -4401,6 +4410,7 @@ UUFlowManager.timeoutAutoSubmit = async function (ins_id) {
|
|
|
4401
4410
|
|
|
4402
4411
|
// Only process if trace is not finished and due_date has passed
|
|
4403
4412
|
if (trace.is_finished || !trace.due_date || new Date(trace.due_date) > new Date()) {
|
|
4413
|
+
console.log(`[timeout_auto_submit] Skipping instance ${instance_id}: trace finished=${trace.is_finished}, due_date=${trace.due_date}, now=${new Date()}`);
|
|
4404
4414
|
continue;
|
|
4405
4415
|
}
|
|
4406
4416
|
|
|
@@ -4431,8 +4441,21 @@ UUFlowManager.timeoutAutoSubmit = async function (ins_id) {
|
|
|
4431
4441
|
|
|
4432
4442
|
// Process each unfinished approve in the trace sequentially to avoid race conditions
|
|
4433
4443
|
const unfinishedApproves = trace.approves.filter(a => !a.is_finished);
|
|
4444
|
+
console.log(`[timeout_auto_submit] Instance ${instance_id}: Processing ${unfinishedApproves.length} unfinished approve(s) | flow=${flow_id} | step=${trace.step} | type=${step_type}`);
|
|
4445
|
+
|
|
4446
|
+
let successCount = 0;
|
|
4447
|
+
let failureCount_approves = 0;
|
|
4448
|
+
let skipCount = 0;
|
|
4434
4449
|
for (const a of unfinishedApproves) {
|
|
4435
4450
|
try {
|
|
4451
|
+
// Check failure count for this approve
|
|
4452
|
+
const failureCount = a.timeout_auto_submit_failures || 0;
|
|
4453
|
+
if (failureCount >= 3) {
|
|
4454
|
+
console.log(`[timeout_auto_submit] Skipping approve ${a._id} - exceeded max failures (count=${failureCount}), instance: ${instance_id}`);
|
|
4455
|
+
skipCount++;
|
|
4456
|
+
continue;
|
|
4457
|
+
}
|
|
4458
|
+
|
|
4436
4459
|
// Create a separate approve_from_client for each approve to avoid shared mutation
|
|
4437
4460
|
const approve_from_client = {
|
|
4438
4461
|
_id: a._id,
|
|
@@ -4455,31 +4478,62 @@ UUFlowManager.timeoutAutoSubmit = async function (ins_id) {
|
|
|
4455
4478
|
continue;
|
|
4456
4479
|
}
|
|
4457
4480
|
|
|
4458
|
-
console.log(`[timeout_auto_submit] Processing approve ${a._id} for instance ${instance_id}`);
|
|
4481
|
+
console.log(`[timeout_auto_submit] Processing approve ${a._id} for instance ${instance_id} (failure_count=${failureCount})`);
|
|
4459
4482
|
console.log(`[timeout_auto_submit] current_user_info: ${JSON.stringify(current_user_info)}`);
|
|
4460
4483
|
|
|
4461
4484
|
const updatedInstance = await UUFlowManager.workflow_engine(
|
|
4462
|
-
approve_from_client,
|
|
4463
|
-
current_user_info,
|
|
4464
|
-
current_user_info._id,
|
|
4485
|
+
approve_from_client,
|
|
4486
|
+
current_user_info,
|
|
4487
|
+
current_user_info._id,
|
|
4465
4488
|
true
|
|
4466
4489
|
);
|
|
4467
4490
|
|
|
4468
4491
|
await pushManager.send_instance_notification(
|
|
4469
|
-
"auto_submit_pending_inbox",
|
|
4470
|
-
updatedInstance,
|
|
4471
|
-
"",
|
|
4492
|
+
"auto_submit_pending_inbox",
|
|
4493
|
+
updatedInstance,
|
|
4494
|
+
"",
|
|
4472
4495
|
current_user_info
|
|
4473
4496
|
);
|
|
4497
|
+
successCount++;
|
|
4474
4498
|
} catch (approveError) {
|
|
4475
|
-
|
|
4499
|
+
const failureCount = (a.timeout_auto_submit_failures || 0) + 1;
|
|
4500
|
+
console.error(`[timeout_auto_submit] Error processing approve ${a._id} for instance ${instance_id} (failure_count=${failureCount}): ${approveError.message || approveError}`);
|
|
4501
|
+
|
|
4502
|
+
// Update the failure count in the database
|
|
4503
|
+
try {
|
|
4504
|
+
await db.instances.updateOne(
|
|
4505
|
+
{
|
|
4506
|
+
_id: instance_id,
|
|
4507
|
+
"traces._id": trace._id
|
|
4508
|
+
},
|
|
4509
|
+
{
|
|
4510
|
+
$set: {
|
|
4511
|
+
"traces.$[trace].approves.$[approve].timeout_auto_submit_failures": failureCount
|
|
4512
|
+
}
|
|
4513
|
+
},
|
|
4514
|
+
{
|
|
4515
|
+
arrayFilters: [
|
|
4516
|
+
{ "trace._id": trace._id },
|
|
4517
|
+
{ "approve._id": a._id }
|
|
4518
|
+
]
|
|
4519
|
+
}
|
|
4520
|
+
);
|
|
4521
|
+
console.log(`[timeout_auto_submit] Updated failure count for approve ${a._id}: ${failureCount}`);
|
|
4522
|
+
} catch (updateError) {
|
|
4523
|
+
console.error(`[timeout_auto_submit] Failed to update failure count for approve ${a._id}: `, updateError.message || updateError);
|
|
4524
|
+
}
|
|
4525
|
+
failureCount_approves++;
|
|
4476
4526
|
}
|
|
4477
4527
|
}
|
|
4528
|
+
console.log(`[timeout_auto_submit] Instance ${instance_id} completed: success=${successCount} | failed=${failureCount_approves} | skipped=${skipCount}`);
|
|
4478
4529
|
} catch (error) {
|
|
4479
4530
|
console.error(`[timeout_auto_submit] Error processing instance ${ins._id}: `, error.stack);
|
|
4480
4531
|
}
|
|
4481
4532
|
}
|
|
4482
4533
|
|
|
4534
|
+
const duration = Date.now() - startTime;
|
|
4535
|
+
console.log(`[timeout_auto_submit] Completed processing ${instances.length} instance(s) in ${duration}ms`);
|
|
4536
|
+
|
|
4483
4537
|
return true;
|
|
4484
4538
|
};
|
|
4485
4539
|
|
package/package.json
CHANGED
|
@@ -484,9 +484,19 @@ InstanceRecordQueue.Configure = function (options) {
|
|
|
484
484
|
}
|
|
485
485
|
|
|
486
486
|
// Universal send function
|
|
487
|
-
var _querySend = function (doc) {
|
|
487
|
+
var _querySend = async function (doc) {
|
|
488
|
+
console.log(`[InstanceRecordQueue._querySend] 开始调用 sendDoc: docId=${doc._id}, insId=${doc.info.instance_id}`);
|
|
488
489
|
if (InstanceRecordQueue.sendDoc) {
|
|
489
|
-
|
|
490
|
+
try {
|
|
491
|
+
await InstanceRecordQueue.sendDoc(doc);
|
|
492
|
+
console.log(`[InstanceRecordQueue._querySend] sendDoc 执行完成: docId=${doc._id}`);
|
|
493
|
+
} catch (error) {
|
|
494
|
+
console.error(`[InstanceRecordQueue._querySend] sendDoc 执行异常: docId=${doc._id}, error=${error.message}`);
|
|
495
|
+
console.error(`[InstanceRecordQueue._querySend] 错误堆栈: ${error.stack}`);
|
|
496
|
+
throw error;
|
|
497
|
+
}
|
|
498
|
+
} else {
|
|
499
|
+
console.warn(`[InstanceRecordQueue._querySend] InstanceRecordQueue.sendDoc 未定义! docId=${doc._id}`);
|
|
490
500
|
}
|
|
491
501
|
|
|
492
502
|
return {
|
|
@@ -494,18 +504,20 @@ InstanceRecordQueue.Configure = function (options) {
|
|
|
494
504
|
};
|
|
495
505
|
};
|
|
496
506
|
|
|
497
|
-
self.serverSend = function (doc) {
|
|
507
|
+
self.serverSend = async function (doc) {
|
|
498
508
|
doc = doc || {};
|
|
499
|
-
return _querySend(doc);
|
|
509
|
+
return await _querySend(doc);
|
|
500
510
|
};
|
|
501
511
|
|
|
502
512
|
var isSendingDoc = false;
|
|
503
513
|
|
|
504
514
|
if (options.sendInterval !== null) {
|
|
505
515
|
var sendDoc = async function (doc) {
|
|
516
|
+
console.log(`[InstanceRecordQueue.sendDoc-queue] 处理队列文档: docId=${doc._id}, insId=${doc.info.instance_id}`);
|
|
506
517
|
// Reserve doc
|
|
507
518
|
var now = +new Date();
|
|
508
519
|
var timeoutAt = now + options.sendTimeout;
|
|
520
|
+
console.log(`[InstanceRecordQueue.sendDoc-queue] 尝试 reserve 文档: docId=${doc._id}, now=${now}, timeoutAt=${timeoutAt}`);
|
|
509
521
|
var reserved = await InstanceRecordQueue.collection.update({
|
|
510
522
|
_id: doc._id,
|
|
511
523
|
sent: false, // xxx: need to make sure this is set on create
|
|
@@ -520,16 +532,20 @@ InstanceRecordQueue.Configure = function (options) {
|
|
|
520
532
|
|
|
521
533
|
// Make sure we only handle docs reserved by this instance
|
|
522
534
|
if (reserved) {
|
|
535
|
+
console.log(`[InstanceRecordQueue.sendDoc-queue] 文档 reserve 成功: docId=${doc._id}, 开始调用 serverSend`);
|
|
523
536
|
// Send
|
|
524
537
|
var result = await self.serverSend(doc);
|
|
538
|
+
console.log(`[InstanceRecordQueue.sendDoc-queue] serverSend 返回结果: docId=${doc._id}, result=${JSON.stringify(result)}`);
|
|
525
539
|
|
|
526
540
|
if (!options.keepDocs) {
|
|
527
541
|
// Pr. Default we will remove docs
|
|
542
|
+
console.log(`[InstanceRecordQueue.sendDoc-queue] keepDocs=false, 删除文档: docId=${doc._id}`);
|
|
528
543
|
await InstanceRecordQueue.collection.remove({
|
|
529
544
|
_id: doc._id
|
|
530
545
|
});
|
|
531
546
|
} else {
|
|
532
547
|
// Update
|
|
548
|
+
console.log(`[InstanceRecordQueue.sendDoc-queue] keepDocs=true, 设置 sent=true: docId=${doc._id}`);
|
|
533
549
|
await InstanceRecordQueue.collection.update({
|
|
534
550
|
_id: doc._id
|
|
535
551
|
}, {
|
|
@@ -543,11 +559,15 @@ InstanceRecordQueue.Configure = function (options) {
|
|
|
543
559
|
}
|
|
544
560
|
});
|
|
545
561
|
}
|
|
562
|
+
} else {
|
|
563
|
+
console.warn(`[InstanceRecordQueue.sendDoc-queue] 文档 reserve 失败(可能被其他实例处理): docId=${doc._id}`);
|
|
546
564
|
} // Else could not reserve
|
|
547
565
|
}; // EO sendDoc
|
|
548
566
|
|
|
549
567
|
sendWorker(async function () {
|
|
568
|
+
console.log(`[InstanceRecordQueue.sendWorker] 定时器触发,开始处理待发送文档...`);
|
|
550
569
|
if (isSendingDoc) {
|
|
570
|
+
console.log(`[InstanceRecordQueue.sendWorker] 上一次还在处理中,跳过本次轮询`);
|
|
551
571
|
return;
|
|
552
572
|
}
|
|
553
573
|
// Set send fence
|
|
@@ -557,6 +577,7 @@ InstanceRecordQueue.Configure = function (options) {
|
|
|
557
577
|
|
|
558
578
|
var now = +new Date();
|
|
559
579
|
|
|
580
|
+
console.log(`[InstanceRecordQueue.sendWorker] 查询待处理文档: batchSize=${batchSize}, now=${now}`);
|
|
560
581
|
// Find docs that are not being or already sent
|
|
561
582
|
var pendingDocs = await InstanceRecordQueue.collection.find({
|
|
562
583
|
$and: [
|
|
@@ -584,10 +605,14 @@ InstanceRecordQueue.Configure = function (options) {
|
|
|
584
605
|
},
|
|
585
606
|
limit: batchSize
|
|
586
607
|
}).toArray();
|
|
608
|
+
console.log(`[InstanceRecordQueue.sendWorker] 找到待处理文档数: ${pendingDocs.length}`);
|
|
609
|
+
|
|
587
610
|
for (const doc of pendingDocs) {
|
|
588
611
|
try {
|
|
612
|
+
console.log(`[InstanceRecordQueue.sendWorker] 处理文档: docId=${doc._id}, insId=${doc.info.instance_id}`);
|
|
589
613
|
await sendDoc(doc);
|
|
590
614
|
} catch (error) {
|
|
615
|
+
console.error(`[InstanceRecordQueue.sendWorker] 文档处理异常: docId=${doc._id}`);
|
|
591
616
|
console.error(error.stack);
|
|
592
617
|
console.log('InstanceRecordQueue: Could not send doc id: "' + doc._id + '", Error: ' + error.message);
|
|
593
618
|
await InstanceRecordQueue.collection.update({
|
|
@@ -603,6 +628,7 @@ InstanceRecordQueue.Configure = function (options) {
|
|
|
603
628
|
|
|
604
629
|
// Remove the send fence
|
|
605
630
|
isSendingDoc = false;
|
|
631
|
+
console.log(`[InstanceRecordQueue.sendWorker] 本次轮询完成,已处理 ${pendingDocs.length} 个文档`);
|
|
606
632
|
}, options.sendInterval || 15000); // Default every 15th sec
|
|
607
633
|
} else {
|
|
608
634
|
if (InstanceRecordQueue.debug) {
|
|
@@ -1259,7 +1285,6 @@ InstanceRecordQueue.sendDoc = async function (doc) {
|
|
|
1259
1285
|
try {
|
|
1260
1286
|
var sync_attachment = ow.sync_attachment,
|
|
1261
1287
|
newRecordId = await makeNewID(ow.object_name),
|
|
1262
|
-
objectName = ow.object_name,
|
|
1263
1288
|
syncDirection = ow.sync_direction || 'both';
|
|
1264
1289
|
lock_record_after_approval = ow.lock_record_after_approval || false;
|
|
1265
1290
|
|
|
@@ -54,12 +54,16 @@ TimeoutAutoSubmit.Configure = function (options = {}) {
|
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
56
|
_isProcessing = true;
|
|
57
|
+
const startTime = Date.now();
|
|
57
58
|
try {
|
|
58
|
-
console.
|
|
59
|
+
console.log('[timeout_auto_submit] Starting timeout auto-submit check...');
|
|
59
60
|
await UUFlowManager.timeoutAutoSubmit();
|
|
60
|
-
|
|
61
|
+
const duration = Date.now() - startTime;
|
|
62
|
+
console.log(`[timeout_auto_submit] Completed in ${duration}ms`);
|
|
61
63
|
} catch (error) {
|
|
62
|
-
|
|
64
|
+
const duration = Date.now() - startTime;
|
|
65
|
+
console.error(`[timeout_auto_submit] Fatal error after ${duration}ms: ${error.message}`);
|
|
66
|
+
console.error('[timeout_auto_submit] Stack trace:', error.stack);
|
|
63
67
|
} finally {
|
|
64
68
|
_isProcessing = false;
|
|
65
69
|
}
|