plugin-cluster-manager 1.1.10 → 1.1.13

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 (119) hide show
  1. package/client-v2.d.ts +2 -0
  2. package/client-v2.js +1 -0
  3. package/client.js +1 -0
  4. package/dist/client/index.js +1 -1
  5. package/dist/client-v2/914.5dc1105cf3ada6a6.js +10 -0
  6. package/dist/client-v2/index.js +10 -0
  7. package/dist/externalVersion.js +6 -5
  8. package/dist/locale/en-US.json +138 -28
  9. package/dist/locale/vi-VN.json +139 -28
  10. package/dist/locale/zh-CN.json +140 -28
  11. package/dist/server/actions/cache-monitor.js +301 -0
  12. package/dist/server/actions/cluster-nodes.js +391 -11
  13. package/dist/server/actions/doctor.js +1246 -0
  14. package/dist/server/actions/orchestrator.js +37 -0
  15. package/dist/server/actions/queue-mappings.js +107 -0
  16. package/dist/server/collections/cluster-manager-doctor-runs.js +52 -0
  17. package/dist/server/collections/cluster-manager-doctor.js +44 -0
  18. package/dist/server/collections/worker-queue-mappings.js +106 -0
  19. package/dist/server/hooks/cacheInvalidationHooks.js +81 -0
  20. package/dist/server/middlewares/listMetaCacheMiddleware.js +79 -0
  21. package/dist/server/orchestrator/PackageManager.js +21 -24
  22. package/dist/server/orchestrator/docker-adapter.js +49 -27
  23. package/dist/server/plugin.js +71 -16
  24. package/dist/server/queue-scanner.js +141 -0
  25. package/dist/server/utils/node.js +30 -2
  26. package/dist/server/utils/versionManager.js +91 -0
  27. package/package.json +9 -5
  28. package/server.js +1 -0
  29. package/src/client/AclCacheManager.tsx +292 -287
  30. package/src/client/CacheMonitor.tsx +166 -179
  31. package/src/client/ClusterManagerLayout.tsx +54 -42
  32. package/src/client/ClusterNodes.tsx +698 -418
  33. package/src/client/ContainerOrchestrator.tsx +184 -102
  34. package/src/client/Doctor.tsx +559 -0
  35. package/src/client/NginxCacheManager.tsx +415 -0
  36. package/src/client/PluginOperations.tsx +234 -234
  37. package/src/client/QueueAssignment.tsx +355 -0
  38. package/src/client/TaskManager.tsx +194 -187
  39. package/src/client/WorkflowExecutions.tsx +243 -238
  40. package/src/client/index.tsx +22 -14
  41. package/src/client/utils/clientSafeCache.ts +41 -0
  42. package/src/client/utils/requestDedupInterceptor.ts +213 -0
  43. package/src/client-v2/plugin.tsx +24 -0
  44. package/src/locale/en-US.json +138 -28
  45. package/src/locale/vi-VN.json +139 -28
  46. package/src/locale/zh-CN.json +140 -28
  47. package/src/server/__tests__/doctor.test.ts +53 -0
  48. package/src/server/actions/acl-cache.ts +272 -272
  49. package/src/server/actions/cache-monitor.ts +453 -116
  50. package/src/server/actions/cluster-nodes.ts +878 -378
  51. package/src/server/actions/doctor.ts +1536 -0
  52. package/src/server/actions/orchestrator.ts +54 -2
  53. package/src/server/actions/queue-mappings.ts +94 -0
  54. package/src/server/collections/cluster-manager-doctor-runs.ts +23 -0
  55. package/src/server/collections/cluster-manager-doctor.ts +19 -0
  56. package/src/server/collections/worker-queue-mappings.ts +85 -0
  57. package/src/server/hooks/cacheInvalidationHooks.ts +58 -0
  58. package/src/server/middlewares/listMetaCacheMiddleware.ts +55 -0
  59. package/src/server/orchestrator/PackageManager.ts +20 -24
  60. package/src/server/orchestrator/docker-adapter.ts +74 -37
  61. package/src/server/plugin.ts +347 -270
  62. package/src/server/queue-scanner.ts +154 -0
  63. package/src/server/utils/node.ts +48 -0
  64. package/src/server/utils/versionManager.ts +69 -0
  65. package/dist/client/AclCacheManager.d.ts +0 -2
  66. package/dist/client/CacheMonitor.d.ts +0 -2
  67. package/dist/client/ClusterManagerLayout.d.ts +0 -2
  68. package/dist/client/ClusterNodes.d.ts +0 -2
  69. package/dist/client/ContainerOrchestrator.d.ts +0 -2
  70. package/dist/client/EventQueueMonitor.d.ts +0 -2
  71. package/dist/client/LockMonitor.d.ts +0 -2
  72. package/dist/client/PackageInstaller.d.ts +0 -2
  73. package/dist/client/PluginOperations.d.ts +0 -2
  74. package/dist/client/RedisMonitor.d.ts +0 -2
  75. package/dist/client/TaskManager.d.ts +0 -2
  76. package/dist/client/WorkflowExecutions.d.ts +0 -2
  77. package/dist/client/index.d.ts +0 -5
  78. package/dist/client/utils.d.ts +0 -12
  79. package/dist/index.d.ts +0 -2
  80. package/dist/server/actions/acl-cache.d.ts +0 -53
  81. package/dist/server/actions/cache-monitor.d.ts +0 -23
  82. package/dist/server/actions/cluster-nodes.d.ts +0 -49
  83. package/dist/server/actions/event-queue-monitor.d.ts +0 -13
  84. package/dist/server/actions/lock-monitor.d.ts +0 -19
  85. package/dist/server/actions/orchestrator.d.ts +0 -58
  86. package/dist/server/actions/package-manager.d.ts +0 -6
  87. package/dist/server/actions/plugin-operations.d.ts +0 -6
  88. package/dist/server/actions/redis-monitor.d.ts +0 -12
  89. package/dist/server/actions/tasks.d.ts +0 -7
  90. package/dist/server/actions/workflow-executions.d.ts +0 -7
  91. package/dist/server/adapters/redis-lock-adapter.d.ts +0 -15
  92. package/dist/server/adapters/redis-node-registry.d.ts +0 -12
  93. package/dist/server/adapters/redis-pubsub-adapter.d.ts +0 -16
  94. package/dist/server/collections/app.d.ts +0 -8
  95. package/dist/server/collections/cluster-manager-acl-cache.d.ts +0 -22
  96. package/dist/server/collections/cluster-manager-cache-mgr.d.ts +0 -22
  97. package/dist/server/collections/cluster-manager-cluster.d.ts +0 -22
  98. package/dist/server/collections/cluster-manager-lock.d.ts +0 -22
  99. package/dist/server/collections/cluster-manager-plugins.d.ts +0 -18
  100. package/dist/server/collections/cluster-manager-queue.d.ts +0 -22
  101. package/dist/server/collections/cluster-manager-redis.d.ts +0 -22
  102. package/dist/server/collections/cluster-manager-workflow.d.ts +0 -22
  103. package/dist/server/collections/cluster-manager.d.ts +0 -22
  104. package/dist/server/collections/orchestrator-settings.d.ts +0 -59
  105. package/dist/server/collections/orchestrator-stacks.d.ts +0 -102
  106. package/dist/server/collections/worker-orchestrator.d.ts +0 -22
  107. package/dist/server/collections/worker-packages-configs.d.ts +0 -3
  108. package/dist/server/collections/worker-packages.d.ts +0 -22
  109. package/dist/server/orchestrator/PackageManager.d.ts +0 -39
  110. package/dist/server/orchestrator/docker-adapter.d.ts +0 -41
  111. package/dist/server/orchestrator/index.d.ts +0 -4
  112. package/dist/server/orchestrator/k8s-adapter.d.ts +0 -50
  113. package/dist/server/orchestrator/leader-election.d.ts +0 -48
  114. package/dist/server/orchestrator/types.d.ts +0 -84
  115. package/dist/server/plugin.d.ts +0 -26
  116. package/dist/server/utils/node.d.ts +0 -6
  117. package/dist/server/utils/redis.d.ts +0 -29
  118. package/dist/shared/packages.d.ts +0 -23
  119. /package/{dist/server/index.d.ts → src/client-v2/index.tsx} +0 -0
@@ -1,179 +1,166 @@
1
- import React, { useState, useEffect, useCallback } from 'react';
2
- import { Card, Table, Tag, Button, Space, Row, Col, Statistic, Tabs, Spin, Popconfirm, message } from 'antd';
3
- import {
4
- ReloadOutlined,
5
- DatabaseOutlined,
6
- DeleteOutlined,
7
- } from '@ant-design/icons';
8
- import { useAPIClient } from '@nocobase/client';
9
- import { AclCacheManager } from './AclCacheManager';
10
- import { RedisMonitor } from './RedisMonitor';
11
- import { LockMonitor } from './LockMonitor';
12
- import { EventQueueMonitor } from './EventQueueMonitor';
13
- import { useT } from './utils';
14
-
15
- export function CacheMonitor() {
16
- const t = useT();
17
- const api = useAPIClient();
18
- const [loading, setLoading] = useState(false);
19
- const [stores, setStores] = useState<any[]>([]);
20
- const [caches, setCaches] = useState<any[]>([]);
21
- const [redisMemory, setRedisMemory] = useState<any>(null);
22
-
23
- const fetchData = useCallback(async () => {
24
- setLoading(true);
25
- try {
26
- const [storesRes, cachesRes, memRes] = await Promise.all([
27
- api.request({ url: 'clusterManagerCacheMgr:stores' }),
28
- api.request({ url: 'clusterManagerCacheMgr:caches' }),
29
- api.request({ url: 'clusterManagerCacheMgr:redisMemory' }),
30
- ]);
31
- setStores(storesRes?.data?.data?.data || []);
32
- setCaches(cachesRes?.data?.data?.data || []);
33
- setRedisMemory(memRes?.data?.data);
34
- } catch {
35
- // Ignore
36
- } finally {
37
- setLoading(false);
38
- }
39
- }, [api]);
40
-
41
- useEffect(() => {
42
- fetchData();
43
- }, [fetchData]);
44
-
45
- const handleFlushAll = async () => {
46
- try {
47
- await api.request({ url: 'clusterManagerCacheMgr:flushAll', method: 'post' });
48
- message.success(t('All caches flushed'));
49
- fetchData();
50
- } catch {
51
- message.error(t('Failed to flush caches'));
52
- }
53
- };
54
-
55
- const storeColumns = [
56
- { title: t('Store Name'), dataIndex: 'name', key: 'name' },
57
- {
58
- title: t('Type'),
59
- dataIndex: 'type',
60
- key: 'type',
61
- width: 120,
62
- render: (v: string) => <Tag color={v === 'redis' ? 'blue' : 'default'}>{v}</Tag>,
63
- },
64
- {
65
- title: t('Default'),
66
- dataIndex: 'isDefault',
67
- key: 'isDefault',
68
- width: 100,
69
- render: (v: boolean) => (v ? <Tag color="green">Yes</Tag> : '-'),
70
- },
71
- ];
72
-
73
- const cacheColumns = [
74
- { title: t('Cache Name'), dataIndex: 'name', key: 'name' },
75
- {
76
- title: t('Prefix'),
77
- dataIndex: 'prefix',
78
- key: 'prefix',
79
- render: (v: string | null) => (v ? <code style={{ fontSize: 11 }}>{v}</code> : '-'),
80
- },
81
- ];
82
-
83
- return (
84
- <Tabs
85
- defaultActiveKey="overview"
86
- items={[
87
- {
88
- key: 'overview',
89
- label: t('Cache Stores'),
90
- children: (
91
- <Spin spinning={loading}>
92
- <Space direction="vertical" style={{ width: '100%' }} size="middle">
93
- <Space>
94
- <Button icon={<ReloadOutlined />} onClick={fetchData}>{t('Refresh')}</Button>
95
- <Popconfirm
96
- title={t('Flush all caches?')}
97
- description={t('This will clear all cached data across all stores.')}
98
- onConfirm={handleFlushAll}
99
- >
100
- <Button danger icon={<DeleteOutlined />}>{t('Flush All')}</Button>
101
- </Popconfirm>
102
- </Space>
103
-
104
- <Row gutter={16}>
105
- <Col span={8}>
106
- <Card size="small">
107
- <Statistic
108
- title={t('Cache Stores')}
109
- value={stores.length}
110
- prefix={<DatabaseOutlined />}
111
- />
112
- </Card>
113
- </Col>
114
- <Col span={8}>
115
- <Card size="small">
116
- <Statistic
117
- title={t('Named Caches')}
118
- value={caches.length}
119
- />
120
- </Card>
121
- </Col>
122
- <Col span={8}>
123
- <Card size="small">
124
- <Statistic
125
- title={t('Redis Keys')}
126
- value={redisMemory?.available ? redisMemory.totalKeys : '-'}
127
- suffix={redisMemory?.available ? `(${redisMemory.usedMemory})` : ''}
128
- />
129
- </Card>
130
- </Col>
131
- </Row>
132
-
133
- <Card title={t('Registered Stores')} size="small">
134
- <Table
135
- dataSource={stores}
136
- columns={storeColumns}
137
- rowKey="name"
138
- size="small"
139
- pagination={false}
140
- />
141
- </Card>
142
-
143
- <Card title={t('Named Caches')} size="small">
144
- <Table
145
- dataSource={caches}
146
- columns={cacheColumns}
147
- rowKey="name"
148
- size="small"
149
- pagination={false}
150
- />
151
- </Card>
152
- </Space>
153
- </Spin>
154
- ),
155
- },
156
- {
157
- key: 'acl',
158
- label: t('ACL Cache'),
159
- children: <AclCacheManager />,
160
- },
161
- {
162
- key: 'redis',
163
- label: t('Redis Monitor'),
164
- children: <RedisMonitor />,
165
- },
166
- {
167
- key: 'locks',
168
- label: t('Locks'),
169
- children: <LockMonitor />,
170
- },
171
- {
172
- key: 'queue',
173
- label: t('Event Queue'),
174
- children: <EventQueueMonitor />,
175
- },
176
- ]}
177
- />
178
- );
179
- }
1
+ import React, { useState, useEffect, useCallback } from 'react';
2
+ import { Card, Table, Tag, Button, Space, Row, Col, Statistic, Tabs, Spin, Popconfirm, message } from 'antd';
3
+ import { ReloadOutlined, DatabaseOutlined, DeleteOutlined } from '@ant-design/icons';
4
+ import { useAPIClient } from '@nocobase/client';
5
+ import { AclCacheManager } from './AclCacheManager';
6
+ import { RedisMonitor } from './RedisMonitor';
7
+ import { LockMonitor } from './LockMonitor';
8
+ import { EventQueueMonitor } from './EventQueueMonitor';
9
+ import { NginxCacheManager } from './NginxCacheManager';
10
+ import { useT } from './utils';
11
+
12
+ export function CacheMonitor() {
13
+ const t = useT();
14
+ const api = useAPIClient();
15
+ const [loading, setLoading] = useState(false);
16
+ const [stores, setStores] = useState<any[]>([]);
17
+ const [caches, setCaches] = useState<any[]>([]);
18
+ const [redisMemory, setRedisMemory] = useState<any>(null);
19
+
20
+ const fetchData = useCallback(async () => {
21
+ setLoading(true);
22
+ try {
23
+ const [storesRes, cachesRes, memRes] = await Promise.all([
24
+ api.request({ url: 'clusterManagerCacheMgr:stores' }),
25
+ api.request({ url: 'clusterManagerCacheMgr:caches' }),
26
+ api.request({ url: 'clusterManagerCacheMgr:redisMemory' }),
27
+ ]);
28
+ setStores(storesRes?.data?.data?.data || []);
29
+ setCaches(cachesRes?.data?.data?.data || []);
30
+ setRedisMemory(memRes?.data?.data);
31
+ } catch {
32
+ // Ignore
33
+ } finally {
34
+ setLoading(false);
35
+ }
36
+ }, [api]);
37
+
38
+ useEffect(() => {
39
+ fetchData();
40
+ }, [fetchData]);
41
+
42
+ const handleFlushAll = async () => {
43
+ try {
44
+ await api.request({ url: 'clusterManagerCacheMgr:flushAll', method: 'post' });
45
+ message.success(t('All caches flushed'));
46
+ fetchData();
47
+ } catch {
48
+ message.error(t('Failed to flush caches'));
49
+ }
50
+ };
51
+
52
+ const storeColumns = [
53
+ { title: t('Store Name'), dataIndex: 'name', key: 'name' },
54
+ {
55
+ title: t('Type'),
56
+ dataIndex: 'type',
57
+ key: 'type',
58
+ width: 120,
59
+ render: (v: string) => <Tag color={v === 'redis' ? 'blue' : 'default'}>{v}</Tag>,
60
+ },
61
+ {
62
+ title: t('Default'),
63
+ dataIndex: 'isDefault',
64
+ key: 'isDefault',
65
+ width: 100,
66
+ render: (v: boolean) => (v ? <Tag color="green">Yes</Tag> : '-'),
67
+ },
68
+ ];
69
+
70
+ const cacheColumns = [
71
+ { title: t('Cache Name'), dataIndex: 'name', key: 'name' },
72
+ {
73
+ title: t('Prefix'),
74
+ dataIndex: 'prefix',
75
+ key: 'prefix',
76
+ render: (v: string | null) => (v ? <code style={{ fontSize: 11 }}>{v}</code> : '-'),
77
+ },
78
+ ];
79
+
80
+ return (
81
+ <Tabs
82
+ defaultActiveKey="overview"
83
+ items={[
84
+ {
85
+ key: 'overview',
86
+ label: t('Cache Stores'),
87
+ children: (
88
+ <Spin spinning={loading}>
89
+ <Space direction="vertical" style={{ width: '100%' }} size="middle">
90
+ <Space>
91
+ <Button icon={<ReloadOutlined />} onClick={fetchData}>
92
+ {t('Refresh')}
93
+ </Button>
94
+ <Popconfirm
95
+ title={t('Flush all caches?')}
96
+ description={t('This will clear all cached data across all stores.')}
97
+ onConfirm={handleFlushAll}
98
+ >
99
+ <Button danger icon={<DeleteOutlined />}>
100
+ {t('Flush All')}
101
+ </Button>
102
+ </Popconfirm>
103
+ </Space>
104
+
105
+ <Row gutter={16}>
106
+ <Col span={8}>
107
+ <Card size="small">
108
+ <Statistic title={t('Cache Stores')} value={stores.length} prefix={<DatabaseOutlined />} />
109
+ </Card>
110
+ </Col>
111
+ <Col span={8}>
112
+ <Card size="small">
113
+ <Statistic title={t('Named Caches')} value={caches.length} />
114
+ </Card>
115
+ </Col>
116
+ <Col span={8}>
117
+ <Card size="small">
118
+ <Statistic
119
+ title={t('Redis Keys')}
120
+ value={redisMemory?.available ? redisMemory.totalKeys : '-'}
121
+ suffix={redisMemory?.available ? `(${redisMemory.usedMemory})` : ''}
122
+ />
123
+ </Card>
124
+ </Col>
125
+ </Row>
126
+
127
+ <Card title={t('Registered Stores')} size="small">
128
+ <Table dataSource={stores} columns={storeColumns} rowKey="name" size="small" pagination={false} />
129
+ </Card>
130
+
131
+ <Card title={t('Named Caches')} size="small">
132
+ <Table dataSource={caches} columns={cacheColumns} rowKey="name" size="small" pagination={false} />
133
+ </Card>
134
+ </Space>
135
+ </Spin>
136
+ ),
137
+ },
138
+ {
139
+ key: 'acl',
140
+ label: t('ACL Cache'),
141
+ children: <AclCacheManager />,
142
+ },
143
+ {
144
+ key: 'redis',
145
+ label: t('Redis Monitor'),
146
+ children: <RedisMonitor />,
147
+ },
148
+ {
149
+ key: 'locks',
150
+ label: t('Locks'),
151
+ children: <LockMonitor />,
152
+ },
153
+ {
154
+ key: 'queue',
155
+ label: t('Event Queue'),
156
+ children: <EventQueueMonitor />,
157
+ },
158
+ {
159
+ key: 'nginx',
160
+ label: t('Nginx Cache'),
161
+ children: <NginxCacheManager />,
162
+ },
163
+ ]}
164
+ />
165
+ );
166
+ }
@@ -1,46 +1,48 @@
1
- import React from 'react';
2
- import { Tabs } from 'antd';
3
- import { TaskManager } from './TaskManager';
4
- import { WorkflowExecutions } from './WorkflowExecutions';
5
- import { ClusterNodes } from './ClusterNodes';
6
- import { CacheMonitor } from './CacheMonitor';
1
+ import React from 'react';
2
+ import { Tabs } from 'antd';
3
+ import { TaskManager } from './TaskManager';
4
+ import { WorkflowExecutions } from './WorkflowExecutions';
5
+ import { ClusterNodes } from './ClusterNodes';
6
+ import { CacheMonitor } from './CacheMonitor';
7
7
  import { ContainerOrchestrator } from './ContainerOrchestrator';
8
8
  import { PackageInstaller } from './PackageInstaller';
9
9
  import { PluginOperations } from './PluginOperations';
10
+ import { Doctor } from './Doctor';
11
+ import { QueueAssignment } from './QueueAssignment';
10
12
  import { useT } from './utils';
11
-
12
- export function ClusterManagerLayout() {
13
- const t = useT();
14
- return (
15
- <div style={{ padding: 24 }}>
16
- <Tabs
17
- defaultActiveKey="cluster"
18
- items={[
19
- {
20
- key: 'cluster',
21
- label: t('Cluster Nodes'),
22
- children: <ClusterNodes />,
23
- },
24
- {
25
- key: 'tasks',
26
- label: t('Async Tasks'),
27
- children: <TaskManager />,
28
- },
29
- {
30
- key: 'executions',
31
- label: t('Workflow Executions'),
32
- children: <WorkflowExecutions />,
33
- },
34
- {
35
- key: 'cache',
36
- label: t('Cache Monitor'),
37
- children: <CacheMonitor />,
38
- },
39
- {
40
- key: 'orchestrator',
41
- label: t('Container Orchestrator'),
42
- children: <ContainerOrchestrator />,
43
- },
13
+
14
+ export function ClusterManagerLayout() {
15
+ const t = useT();
16
+ return (
17
+ <div style={{ padding: 24 }}>
18
+ <Tabs
19
+ defaultActiveKey="cluster"
20
+ items={[
21
+ {
22
+ key: 'cluster',
23
+ label: t('Cluster Nodes'),
24
+ children: <ClusterNodes />,
25
+ },
26
+ {
27
+ key: 'tasks',
28
+ label: t('Async Tasks'),
29
+ children: <TaskManager />,
30
+ },
31
+ {
32
+ key: 'executions',
33
+ label: t('Workflow Executions'),
34
+ children: <WorkflowExecutions />,
35
+ },
36
+ {
37
+ key: 'cache',
38
+ label: t('Cache Monitor'),
39
+ children: <CacheMonitor />,
40
+ },
41
+ {
42
+ key: 'orchestrator',
43
+ label: t('Container Orchestrator'),
44
+ children: <ContainerOrchestrator />,
45
+ },
44
46
  {
45
47
  key: 'packages',
46
48
  label: t('Packages'),
@@ -51,8 +53,18 @@ export function ClusterManagerLayout() {
51
53
  label: t('Plugins'),
52
54
  children: <PluginOperations />,
53
55
  },
56
+ {
57
+ key: 'doctor',
58
+ label: t('Doctor'),
59
+ children: <Doctor />,
60
+ },
61
+ {
62
+ key: 'queues',
63
+ label: t('Queue Assignment'),
64
+ children: <QueueAssignment />,
65
+ },
54
66
  ]}
55
67
  />
56
- </div>
57
- );
58
- }
68
+ </div>
69
+ );
70
+ }