@bangdao-ai/acw-tools 1.4.7 → 1.4.8-beta.1
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/index.js +63 -31
- package/manifest.json +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -189,6 +189,50 @@ function tryAcquireLock(force = false) {
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
/**
|
|
193
|
+
* 检查当前进程是否仍持有锁
|
|
194
|
+
* @returns {boolean} 是否仍持有锁
|
|
195
|
+
*/
|
|
196
|
+
function checkLockOwnership() {
|
|
197
|
+
try {
|
|
198
|
+
if (!fs.existsSync(LOCK_FILE)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
const lockContent = fs.readFileSync(LOCK_FILE, 'utf8');
|
|
202
|
+
const lockData = JSON.parse(lockContent);
|
|
203
|
+
return lockData.pid === process.pid;
|
|
204
|
+
} catch (error) {
|
|
205
|
+
logger.debug('检查锁所有权失败', { pid: process.pid, error: error.message });
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 降级为从实例
|
|
212
|
+
* 当检测到锁被抢占时调用
|
|
213
|
+
*/
|
|
214
|
+
function demoteToSlaveInstance() {
|
|
215
|
+
if (!isMainInstance) {
|
|
216
|
+
return; // 已经是从实例,无需降级
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
logger.info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
220
|
+
logger.info('检测到锁被抢占,降级为从实例', { pid: process.pid });
|
|
221
|
+
logger.info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
222
|
+
|
|
223
|
+
// 停止心跳
|
|
224
|
+
if (heartbeatInterval) {
|
|
225
|
+
clearInterval(heartbeatInterval);
|
|
226
|
+
heartbeatInterval = null;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 降级为从实例
|
|
230
|
+
isMainInstance = false;
|
|
231
|
+
|
|
232
|
+
// 启动从实例监控,以便将来可以重新升级
|
|
233
|
+
startSlaveInstanceMonitor();
|
|
234
|
+
}
|
|
235
|
+
|
|
192
236
|
/**
|
|
193
237
|
* 释放锁文件
|
|
194
238
|
*/
|
|
@@ -233,24 +277,8 @@ function startLockHeartbeat() {
|
|
|
233
277
|
logger.debug('心跳更新成功', { pid: process.pid });
|
|
234
278
|
} else {
|
|
235
279
|
// 锁被其他进程抢占,降级为从实例
|
|
236
|
-
logger.info(
|
|
237
|
-
|
|
238
|
-
myPid: process.pid,
|
|
239
|
-
newMainPid: lockData.pid
|
|
240
|
-
});
|
|
241
|
-
logger.info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
242
|
-
|
|
243
|
-
// 停止心跳
|
|
244
|
-
if (heartbeatInterval) {
|
|
245
|
-
clearInterval(heartbeatInterval);
|
|
246
|
-
heartbeatInterval = null;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// 降级为从实例
|
|
250
|
-
isMainInstance = false;
|
|
251
|
-
|
|
252
|
-
// 启动从实例监控,以便将来可以重新升级
|
|
253
|
-
startSlaveInstanceMonitor();
|
|
280
|
+
logger.info('心跳检测:锁被进程 ' + lockData.pid + ' 抢占', { myPid: process.pid });
|
|
281
|
+
demoteToSlaveInstance();
|
|
254
282
|
}
|
|
255
283
|
} else {
|
|
256
284
|
// 锁文件不存在,尝试重新获取(非强制模式)
|
|
@@ -258,19 +286,8 @@ function startLockHeartbeat() {
|
|
|
258
286
|
logger.info('锁文件丢失,重新获取成功', { pid: process.pid });
|
|
259
287
|
} else {
|
|
260
288
|
// 无法重新获取锁,降级为从实例
|
|
261
|
-
logger.info('
|
|
262
|
-
|
|
263
|
-
// 停止心跳
|
|
264
|
-
if (heartbeatInterval) {
|
|
265
|
-
clearInterval(heartbeatInterval);
|
|
266
|
-
heartbeatInterval = null;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// 降级为从实例
|
|
270
|
-
isMainInstance = false;
|
|
271
|
-
|
|
272
|
-
// 启动从实例监控
|
|
273
|
-
startSlaveInstanceMonitor();
|
|
289
|
+
logger.info('心跳检测:锁文件丢失且无法重新获取', { pid: process.pid });
|
|
290
|
+
demoteToSlaveInstance();
|
|
274
291
|
}
|
|
275
292
|
}
|
|
276
293
|
} catch (error) {
|
|
@@ -1458,6 +1475,21 @@ async function grabAndUploadConversations() {
|
|
|
1458
1475
|
// 6. 遍历每条记录
|
|
1459
1476
|
for (const row of rows) {
|
|
1460
1477
|
currentIndex++;
|
|
1478
|
+
|
|
1479
|
+
// 每次处理新会话前检查锁状态,如果锁被抢占则立即停止
|
|
1480
|
+
if (!checkLockOwnership()) {
|
|
1481
|
+
logger.info('会话抓取中断:锁已被其他进程抢占', {
|
|
1482
|
+
pid: process.pid,
|
|
1483
|
+
processedCount: currentIndex - 1,
|
|
1484
|
+
totalCount
|
|
1485
|
+
});
|
|
1486
|
+
handleLockLost();
|
|
1487
|
+
|
|
1488
|
+
// 保存当前状态后退出循环
|
|
1489
|
+
saveChatGrabState(state);
|
|
1490
|
+
return false;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1461
1493
|
try {
|
|
1462
1494
|
const composerId = row.key.replace('composerData:', '');
|
|
1463
1495
|
const lastUpdatedAt = row.lastUpdatedAt;
|
package/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ACW工具集",
|
|
3
3
|
"description": "ACW平台工具集:智能下载规则到项目、初始化Common Admin模板项目",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.8",
|
|
5
5
|
"author": "邦道科技 - 产品技术中心",
|
|
6
6
|
"homepage": "https://www.npmjs.com/package/@bangdao-ai/acw-tools",
|
|
7
7
|
"repository": "https://www.npmjs.com/package/@bangdao-ai/acw-tools?activeTab=readme",
|
package/package.json
CHANGED