zen-gitsync 2.16.39 → 2.16.41
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/package.json +1 -1
- package/src/ui/public/assets/{AgentView-DWZx4tNO.js → AgentView-DnxCoGA3.js} +1 -1
- package/src/ui/public/assets/{AppVersionBadge-Crbg_My9.js → AppVersionBadge-BYHep72-.js} +2 -2
- package/src/ui/public/assets/{BranchSelector-D5veuJEK.js → BranchSelector-CxDWJWY9.js} +1 -1
- package/src/ui/public/assets/{CommitForm-DOlVaeAm.js → CommitForm-uOwUV97K.js} +1 -1
- package/src/ui/public/assets/{CommonDialog-ByvhJIxb.js → CommonDialog-Zoo8fqjA.js} +1 -1
- package/src/ui/public/assets/{EditorView-DIWt74ii.js → EditorView-B2lxPjuX.js} +1 -1
- package/src/ui/public/assets/{FlowExecutionViewer-CiK6fWX0.js → FlowExecutionViewer-BUAzBEte.js} +1 -1
- package/src/ui/public/assets/{FlowOrchestrationWorkspace-QzKGpumZ.js → FlowOrchestrationWorkspace-Ca4ROV6g.js} +1 -1
- package/src/ui/public/assets/{LogList-DmvJXefN.js → LogList-CLcg4XNV.js} +1 -1
- package/src/ui/public/assets/{MindmapView-DGbJgFMZ.js → MindmapView-B-w2CfCF.js} +1 -1
- package/src/ui/public/assets/{MonitorView-BlfmRbaV.js → MonitorView-RhIHMXtT.js} +1 -1
- package/src/ui/public/assets/{ProjectStartupButton-Dr8VCQSL.js → ProjectStartupButton-D1woOmfK.js} +1 -1
- package/src/ui/public/assets/{RemoteRepoCard-CrC-ph-p.js → RemoteRepoCard-C00T4duQ.js} +1 -1
- package/src/ui/public/assets/{SourceMapView-BIfkwd0_.js → SourceMapView-BlGFU0dY.js} +1 -1
- package/src/ui/public/assets/{SvgIcon-ryKBwC8P.js → SvgIcon-DniMQk5U.js} +1 -1
- package/src/ui/public/assets/{UserInputNode-8v5LCzR9.js → UserInputNode-D83u028f.js} +1 -1
- package/src/ui/public/assets/{WorkbenchView-KKlaNqT0.js → WorkbenchView-BhZcJVl4.js} +1 -1
- package/src/ui/public/assets/{_plugin-vue_export-helper-C5Vpcpi0.js → _plugin-vue_export-helper-CkojBFWh.js} +2 -2
- package/src/ui/public/assets/{configStore-DdYe2Jg3.js → configStore-BisOZpe4.js} +1 -1
- package/src/ui/public/assets/{index-hyzLLFKf.js → index-CwgZxqFI.js} +6 -6
- package/src/ui/public/assets/index-DLi15Rb_.css +1 -0
- package/src/ui/public/index.html +6 -6
- package/src/ui/server/routes/instances.js +13 -4
- package/src/ui/server/routes/instances.test.js +51 -6
- package/src/ui/public/assets/index-DDmVbc4D.css +0 -1
package/src/ui/public/index.html
CHANGED
|
@@ -10,18 +10,18 @@
|
|
|
10
10
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
11
11
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
12
12
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,400&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
13
|
-
<script type="module" crossorigin src="/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-CwgZxqFI.js"></script>
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-BM3Ffeng.js">
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/monaco-43aputPh.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/element-plus-Cchqf1s7.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/vendor-FHXYVNcm.js">
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-CkojBFWh.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/assets/socket-io-BZIzo1US.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="/assets/vue-flow-3jJr-V2W.js">
|
|
21
21
|
<link rel="modulepreload" crossorigin href="/assets/flow-mindmap-D4bc307Q.js">
|
|
22
|
-
<link rel="modulepreload" crossorigin href="/assets/SvgIcon-
|
|
23
|
-
<link rel="modulepreload" crossorigin href="/assets/CommonDialog-
|
|
24
|
-
<link rel="modulepreload" crossorigin href="/assets/configStore-
|
|
22
|
+
<link rel="modulepreload" crossorigin href="/assets/SvgIcon-DniMQk5U.js">
|
|
23
|
+
<link rel="modulepreload" crossorigin href="/assets/CommonDialog-Zoo8fqjA.js">
|
|
24
|
+
<link rel="modulepreload" crossorigin href="/assets/configStore-BisOZpe4.js">
|
|
25
25
|
<link rel="modulepreload" crossorigin href="/assets/toolsStore-C0VjU2dD.js">
|
|
26
26
|
<link rel="stylesheet" crossorigin href="/assets/monaco-B2lPvkrc.css">
|
|
27
27
|
<link rel="stylesheet" crossorigin href="/assets/element-plus-D3Dn7nX0.css">
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<link rel="stylesheet" crossorigin href="/assets/flow-mindmap-DnzM9SlK.css">
|
|
31
31
|
<link rel="stylesheet" crossorigin href="/assets/SvgIcon-BQ6bR7l0.css">
|
|
32
32
|
<link rel="stylesheet" crossorigin href="/assets/CommonDialog-Cyh3xu0p.css">
|
|
33
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
33
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DLi15Rb_.css">
|
|
34
34
|
</head>
|
|
35
35
|
<body>
|
|
36
36
|
<div id="app"></div>
|
|
@@ -35,7 +35,10 @@ export function registerInstancesRoutes({
|
|
|
35
35
|
});
|
|
36
36
|
}));
|
|
37
37
|
|
|
38
|
-
//
|
|
38
|
+
// 关闭注册表中仍存活的实例(含当前实例,见下方 selfClose 分支)。前端不能传
|
|
39
|
+
// signal 或任意命令。当前实例关闭走和 SIGINT 一样的 graceful shutdown 链路
|
|
40
|
+
// (server/index.js:648 的 SIGTERM handler):drain 子进程 + unregister + exit,
|
|
41
|
+
// 响应先于 SIGTERM 触发发出,所以客户端能拿到 success。
|
|
39
42
|
app.post('/api/instances/:pid/close', asyncRoute(async (req, res) => {
|
|
40
43
|
const pidText = String(req.params?.pid || '');
|
|
41
44
|
if (!/^\d+$/.test(pidText)) {
|
|
@@ -46,9 +49,7 @@ export function registerInstancesRoutes({
|
|
|
46
49
|
const currentInstanceId = typeof getCurrentInstanceId === 'function'
|
|
47
50
|
? getCurrentInstanceId()
|
|
48
51
|
: null;
|
|
49
|
-
|
|
50
|
-
throw new HttpError(400, '不能从当前页面关闭当前实例');
|
|
51
|
-
}
|
|
52
|
+
const isSelfClose = pid === currentInstanceId;
|
|
52
53
|
|
|
53
54
|
const instances = await registry.list({ pruneStale: true });
|
|
54
55
|
const target = instances.find((instance) => instance.pid === pid);
|
|
@@ -73,7 +74,15 @@ export function registerInstancesRoutes({
|
|
|
73
74
|
success: true,
|
|
74
75
|
closedPid: pid,
|
|
75
76
|
message: `已关闭实例 ${target.projectName || pid}`,
|
|
77
|
+
// 标记是否为当前实例。前端靠它决定要不要调 window.close() 关 tab。
|
|
78
|
+
selfClose: isSelfClose,
|
|
76
79
|
});
|
|
80
|
+
if (isSelfClose) {
|
|
81
|
+
// 同步把 SIGTERM 事件 emit 给本进程的 listener(handler 内部 async,且
|
|
82
|
+
// 最后 setTimeout 100ms 才 exit);setImmediate 把 emit 推到下个 tick,
|
|
83
|
+
// 确保上面的 res.json 已同步写到 socket buffer,客户端能收到响应。
|
|
84
|
+
setImmediate(() => process.emit('SIGTERM'));
|
|
85
|
+
}
|
|
77
86
|
}));
|
|
78
87
|
|
|
79
88
|
// 批量关闭注册表中所有非当前实例。逐个走 kill + unregister,失败不影响其他项。
|
|
@@ -47,13 +47,58 @@ test('instances close: 关闭已注册的其他实例并反注册', async () =>
|
|
|
47
47
|
assert.deepEqual(unregistered, [200])
|
|
48
48
|
})
|
|
49
49
|
|
|
50
|
-
test('instances close:
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
test('instances close: 允许关闭当前实例(selfClose=true),并 emit SIGTERM 触发自身 graceful shutdown', async () => {
|
|
51
|
+
// 当前实例的关闭走自身 SIGTERM handler(server/index.js:648),由
|
|
52
|
+
// instances.js 在 res.json 之后 setImmediate(() => process.emit('SIGTERM'))
|
|
53
|
+
// 触发。本测试用一个临时 listener 验证 emit 真的发生了一次。
|
|
54
|
+
const target = { pid: 100, port: 5800, projectName: 'self' }
|
|
55
|
+
let sigtermCount = 0
|
|
56
|
+
const onSigterm = () => { sigtermCount++ }
|
|
57
|
+
process.on('SIGTERM', onSigterm)
|
|
58
|
+
try {
|
|
59
|
+
const { routes, killed, unregistered } = setup({
|
|
60
|
+
currentPid: 100,
|
|
61
|
+
instances: [target],
|
|
62
|
+
})
|
|
63
|
+
const result = await callClose(routes.get('POST /api/instances/:pid/close'), 100)
|
|
64
|
+
|
|
65
|
+
// 等 setImmediate 队列跑完,让 emit SIGTERM 触发 listener
|
|
66
|
+
await new Promise((resolve) => setImmediate(resolve))
|
|
67
|
+
|
|
68
|
+
assert.equal(result.statusCode, 200)
|
|
69
|
+
assert.equal(result.payload.success, true)
|
|
70
|
+
assert.equal(result.payload.selfClose, true, 'should mark current instance as self-close')
|
|
71
|
+
assert.deepEqual(killed, [[100, 'SIGTERM']], 'killProcess 仍要正常调用(SIGTERM handler 真正入口)')
|
|
72
|
+
assert.deepEqual(unregistered, [100])
|
|
73
|
+
assert.equal(sigtermCount, 1, 'self-close 后应 emit 一次 SIGTERM 触发自身 shutdown handler')
|
|
74
|
+
} finally {
|
|
75
|
+
process.off('SIGTERM', onSigterm)
|
|
76
|
+
}
|
|
77
|
+
})
|
|
53
78
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
79
|
+
test('instances close: 关闭其他实例时 selfClose=false,不 emit SIGTERM', async () => {
|
|
80
|
+
const target = { pid: 200, port: 5801, projectName: 'other' }
|
|
81
|
+
let sigtermCount = 0
|
|
82
|
+
const onSigterm = () => { sigtermCount++ }
|
|
83
|
+
process.on('SIGTERM', onSigterm)
|
|
84
|
+
try {
|
|
85
|
+
const { routes, killed, unregistered } = setup({
|
|
86
|
+
currentPid: 100,
|
|
87
|
+
instances: [target],
|
|
88
|
+
})
|
|
89
|
+
const result = await callClose(routes.get('POST /api/instances/:pid/close'), 200)
|
|
90
|
+
|
|
91
|
+
await new Promise((resolve) => setImmediate(resolve))
|
|
92
|
+
|
|
93
|
+
assert.equal(result.statusCode, 200)
|
|
94
|
+
assert.equal(result.payload.success, true)
|
|
95
|
+
assert.equal(result.payload.selfClose, false, 'other instance must not be marked self-close')
|
|
96
|
+
assert.deepEqual(killed, [[200, 'SIGTERM']])
|
|
97
|
+
assert.deepEqual(unregistered, [200])
|
|
98
|
+
assert.equal(sigtermCount, 0, '关闭其他实例不应触发自身 SIGTERM')
|
|
99
|
+
} finally {
|
|
100
|
+
process.off('SIGTERM', onSigterm)
|
|
101
|
+
}
|
|
57
102
|
})
|
|
58
103
|
|
|
59
104
|
test('instances close: 不允许关闭注册表外的 PID', async () => {
|