tanmi-dock 0.8.0 → 0.8.1-beta.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/dist/index.js CHANGED
@@ -47,19 +47,21 @@ async function gracefulShutdown(signal, exitCode) {
47
47
  process.on('SIGINT', () => gracefulShutdown('SIGINT', 130));
48
48
  process.on('SIGTERM', () => gracefulShutdown('SIGTERM', 143));
49
49
  // 全局异常捕获
50
- process.on('uncaughtException', (err) => {
50
+ process.on('uncaughtException', async (err) => {
51
51
  console.error('[err] 发生未预期错误:', err.message);
52
52
  if (process.env.DEBUG) {
53
53
  console.error(err.stack);
54
54
  }
55
55
  console.error('[hint] 如问题持续,请运行 tanmi-dock check 诊断');
56
+ await releaseGlobalLock();
56
57
  process.exit(1);
57
58
  });
58
- process.on('unhandledRejection', (reason) => {
59
+ process.on('unhandledRejection', async (reason) => {
59
60
  console.error('[err] 未处理的 Promise 拒绝:', reason);
60
61
  if (process.env.DEBUG) {
61
62
  console.error(reason);
62
63
  }
64
+ await releaseGlobalLock();
63
65
  process.exit(1);
64
66
  });
65
67
  const program = new Command();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"global-lock.d.ts","sourceRoot":"","sources":["../../src/utils/global-lock.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAiB1D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CASvD;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAQvD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAUxE;;;;;;;AAED,wBAKE"}
1
+ {"version":3,"file":"global-lock.d.ts","sourceRoot":"","sources":["../../src/utils/global-lock.ts"],"names":[],"mappings":"AA2EA;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CA4B1D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CASvD;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAgBvD;AAcD;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAexE;;;;;;;AAED,wBAKE"}
@@ -1,6 +1,9 @@
1
1
  /**
2
2
  * 全局操作锁
3
3
  * 防止多个 tanmi-dock 命令同时执行导致冲突
4
+ *
5
+ * 改进:写入 PID 到锁文件,当持有锁的进程已死时立即清理残留锁,
6
+ * 无需等待 stale 超时。解决进程被 kill/管道中断后锁残留的问题。
4
7
  */
5
8
  import lockfile from 'proper-lockfile';
6
9
  import fs from 'fs/promises';
@@ -14,25 +17,89 @@ let globalLockRelease = null;
14
17
  function getLockPath() {
15
18
  return path.join(getConfigDir(), LOCK_FILE);
16
19
  }
20
+ /**
21
+ * 检查指定 PID 的进程是否仍存活
22
+ */
23
+ function isProcessAlive(pid) {
24
+ try {
25
+ process.kill(pid, 0); // 信号 0 不发送信号,仅检查进程是否存在
26
+ return true;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ /**
33
+ * 从锁文件读取持有者 PID
34
+ * @returns PID 或 null(无法读取/解析时)
35
+ */
36
+ async function readHolderPid(lockPath) {
37
+ try {
38
+ const content = await fs.readFile(lockPath, 'utf-8');
39
+ const pid = parseInt(content.trim(), 10);
40
+ return isNaN(pid) || pid <= 0 ? null : pid;
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /**
47
+ * 强制清理残留的锁目录
48
+ * proper-lockfile 使用 {file}.lock 目录作为实际锁
49
+ */
50
+ async function forceCleanStaleLock(lockPath) {
51
+ const lockDir = `${lockPath}.lock`;
52
+ try {
53
+ await fs.rm(lockDir, { recursive: true, force: true });
54
+ }
55
+ catch {
56
+ // 清理失败不阻塞
57
+ }
58
+ }
59
+ /**
60
+ * 内部:尝试获取锁并写入 PID
61
+ */
62
+ async function tryAcquire(lockPath) {
63
+ globalLockRelease = await lockfile.lock(lockPath, {
64
+ retries: 0,
65
+ stale: 30000, // 30秒后锁过期(兜底机制)
66
+ });
67
+ // 获取成功后写入当前 PID,供其他进程检测
68
+ await fs.writeFile(lockPath, String(process.pid), 'utf-8');
69
+ return true;
70
+ }
17
71
  /**
18
72
  * 获取全局锁
19
73
  * @returns 是否成功获取锁
20
74
  */
21
75
  export async function acquireGlobalLock() {
22
76
  const lockPath = getLockPath();
77
+ // 确保配置目录和锁文件存在
78
+ const dir = path.dirname(lockPath);
79
+ await fs.mkdir(dir, { recursive: true });
23
80
  try {
24
- // 确保配置目录和锁文件存在
25
- const dir = path.dirname(lockPath);
26
- await fs.mkdir(dir, { recursive: true });
27
- await fs.writeFile(lockPath, '', { flag: 'a' }); // 追加模式,文件存在则不覆盖
28
- globalLockRelease = await lockfile.lock(lockPath, {
29
- retries: 0, // 不重试,立即失败
30
- stale: 30000, // 30秒后锁过期(防止进程异常退出后锁不释放)
31
- });
32
- return true;
81
+ await fs.access(lockPath);
82
+ }
83
+ catch {
84
+ await fs.writeFile(lockPath, '', 'utf-8');
85
+ }
86
+ try {
87
+ return await tryAcquire(lockPath);
33
88
  }
34
89
  catch {
35
- return false; // 已有其他进程持有锁
90
+ // 锁获取失败 检查持有者是否仍存活
91
+ const holderPid = await readHolderPid(lockPath);
92
+ if (holderPid !== null && !isProcessAlive(holderPid)) {
93
+ // 持有者进程已死,清理残留锁并重试
94
+ await forceCleanStaleLock(lockPath);
95
+ try {
96
+ return await tryAcquire(lockPath);
97
+ }
98
+ catch {
99
+ return false;
100
+ }
101
+ }
102
+ return false;
36
103
  }
37
104
  }
38
105
  /**
@@ -56,12 +123,31 @@ export async function isGlobalLocked() {
56
123
  const lockPath = getLockPath();
57
124
  try {
58
125
  await fs.access(lockPath);
59
- return await lockfile.check(lockPath);
126
+ const locked = await lockfile.check(lockPath);
127
+ if (!locked)
128
+ return false;
129
+ // 锁存在,但检查持有者是否仍存活
130
+ const holderPid = await readHolderPid(lockPath);
131
+ if (holderPid !== null && !isProcessAlive(holderPid)) {
132
+ return false; // 持有者已死,锁实际是残留的
133
+ }
134
+ return true;
60
135
  }
61
136
  catch {
62
137
  return false;
63
138
  }
64
139
  }
140
+ /**
141
+ * 获取锁的持有者信息(用于错误提示)
142
+ */
143
+ async function getLockHolderInfo() {
144
+ const lockPath = getLockPath();
145
+ const pid = await readHolderPid(lockPath);
146
+ if (pid !== null) {
147
+ return `(PID: ${pid})`;
148
+ }
149
+ return '';
150
+ }
65
151
  /**
66
152
  * 使用全局锁执行操作
67
153
  * @param fn 要执行的操作
@@ -71,7 +157,10 @@ export async function isGlobalLocked() {
71
157
  export async function withGlobalLock(fn) {
72
158
  const acquired = await acquireGlobalLock();
73
159
  if (!acquired) {
74
- throw new Error('另一个 tanmi-dock 命令正在执行,请稍后重试');
160
+ const holderInfo = await getLockHolderInfo();
161
+ const lockDir = `${getLockPath()}.lock`;
162
+ throw new Error(`另一个 tanmi-dock 命令正在执行${holderInfo},请稍后重试\n` +
163
+ `[hint] 如确认无其他命令运行,可手动清理: rm -rf "${lockDir}"`);
75
164
  }
76
165
  try {
77
166
  return await fn();
@@ -1 +1 @@
1
- {"version":3,"file":"global-lock.js","sourceRoot":"","sources":["../../src/utils/global-lock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAEpC,IAAI,iBAAiB,GAAiC,IAAI,CAAC;AAE3D;;GAEG;AACH,SAAS,WAAW;IAClB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,eAAe;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,gBAAgB;QAEjE,iBAAiB,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE;YAChD,OAAO,EAAE,CAAC,EAAE,WAAW;YACvB,KAAK,EAAE,KAAK,EAAE,yBAAyB;SACxC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,YAAY;IAC5B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,iBAAiB,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,iBAAiB,EAAE,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB;QACnB,CAAC;QACD,iBAAiB,GAAG,IAAI,CAAC;IAC3B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,MAAM,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAI,EAAoB;IAC1D,MAAM,QAAQ,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,MAAM,iBAAiB,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,eAAe;IACb,iBAAiB;IACjB,iBAAiB;IACjB,cAAc;IACd,cAAc;CACf,CAAC"}
1
+ {"version":3,"file":"global-lock.js","sourceRoot":"","sources":["../../src/utils/global-lock.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tanmi-dock",
3
- "version": "0.8.0",
3
+ "version": "0.8.1-beta.0",
4
4
  "description": "集中型第三方库链接管理工具",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",