plugin-cluster-manager 1.1.11 → 1.1.15

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 (116) hide show
  1. package/client-v2.d.ts +2 -0
  2. package/client-v2.js +1 -0
  3. package/dist/client/index.js +1 -1
  4. package/dist/client-v2/914.c0bce51908fd81d7.js +10 -0
  5. package/dist/client-v2/index.js +10 -0
  6. package/dist/externalVersion.js +6 -5
  7. package/dist/locale/en-US.json +138 -124
  8. package/dist/locale/vi-VN.json +139 -125
  9. package/dist/locale/zh-CN.json +140 -125
  10. package/dist/server/actions/cluster-nodes.js +2 -6
  11. package/dist/server/actions/doctor.js +1 -5
  12. package/dist/server/actions/orchestrator.js +37 -0
  13. package/dist/server/actions/queue-mappings.js +107 -0
  14. package/dist/server/collections/worker-queue-mappings.js +106 -0
  15. package/dist/server/orchestrator/PackageManager.js +1 -8
  16. package/dist/server/orchestrator/docker-adapter.js +49 -27
  17. package/dist/server/plugin.js +10 -8
  18. package/dist/server/queue-scanner.js +141 -0
  19. package/dist/server/utils/node.js +30 -2
  20. package/package.json +46 -42
  21. package/src/client/AclCacheManager.tsx +292 -287
  22. package/src/client/CacheMonitor.tsx +2 -2
  23. package/src/client/ClusterManagerLayout.tsx +6 -0
  24. package/src/client/ClusterNodes.tsx +11 -4
  25. package/src/client/ContainerOrchestrator.tsx +186 -104
  26. package/src/client/Doctor.tsx +2 -2
  27. package/src/client/EventQueueMonitor.tsx +2 -2
  28. package/src/client/LockMonitor.tsx +2 -2
  29. package/src/client/NginxCacheManager.tsx +2 -2
  30. package/src/client/PackageInstaller.tsx +2 -2
  31. package/src/client/PluginOperations.tsx +2 -2
  32. package/src/client/QueueAssignment.tsx +355 -0
  33. package/src/client/RedisMonitor.tsx +3 -3
  34. package/src/client/TaskManager.tsx +194 -187
  35. package/src/client/WorkflowExecutions.tsx +243 -238
  36. package/src/client/utils.ts +1 -1
  37. package/src/client-v2/plugin.tsx +24 -0
  38. package/src/locale/en-US.json +138 -124
  39. package/src/locale/vi-VN.json +139 -125
  40. package/src/locale/zh-CN.json +140 -125
  41. package/src/server/actions/cluster-nodes.ts +4 -7
  42. package/src/server/actions/doctor.ts +11 -9
  43. package/src/server/actions/orchestrator.ts +54 -2
  44. package/src/server/actions/queue-mappings.ts +94 -0
  45. package/src/server/adapters/redis-node-registry.ts +126 -131
  46. package/src/server/collections/worker-queue-mappings.ts +85 -0
  47. package/src/server/orchestrator/PackageManager.ts +2 -10
  48. package/src/server/orchestrator/docker-adapter.ts +74 -37
  49. package/src/server/plugin.ts +15 -12
  50. package/src/server/queue-scanner.ts +154 -0
  51. package/src/server/utils/node.ts +48 -0
  52. package/dist/client/AclCacheManager.d.ts +0 -2
  53. package/dist/client/CacheMonitor.d.ts +0 -2
  54. package/dist/client/ClusterManagerLayout.d.ts +0 -2
  55. package/dist/client/ClusterNodes.d.ts +0 -2
  56. package/dist/client/ContainerOrchestrator.d.ts +0 -2
  57. package/dist/client/Doctor.d.ts +0 -2
  58. package/dist/client/EventQueueMonitor.d.ts +0 -2
  59. package/dist/client/LockMonitor.d.ts +0 -2
  60. package/dist/client/NginxCacheManager.d.ts +0 -2
  61. package/dist/client/PackageInstaller.d.ts +0 -2
  62. package/dist/client/PluginOperations.d.ts +0 -2
  63. package/dist/client/RedisMonitor.d.ts +0 -2
  64. package/dist/client/TaskManager.d.ts +0 -2
  65. package/dist/client/WorkflowExecutions.d.ts +0 -2
  66. package/dist/client/index.d.ts +0 -5
  67. package/dist/client/utils/clientSafeCache.d.ts +0 -3
  68. package/dist/client/utils/requestDedupInterceptor.d.ts +0 -2
  69. package/dist/client/utils.d.ts +0 -12
  70. package/dist/index.d.ts +0 -2
  71. package/dist/server/actions/acl-cache.d.ts +0 -53
  72. package/dist/server/actions/cache-monitor.d.ts +0 -33
  73. package/dist/server/actions/cluster-nodes.d.ts +0 -64
  74. package/dist/server/actions/doctor.d.ts +0 -82
  75. package/dist/server/actions/event-queue-monitor.d.ts +0 -13
  76. package/dist/server/actions/lock-monitor.d.ts +0 -19
  77. package/dist/server/actions/orchestrator.d.ts +0 -58
  78. package/dist/server/actions/package-manager.d.ts +0 -6
  79. package/dist/server/actions/plugin-operations.d.ts +0 -6
  80. package/dist/server/actions/redis-monitor.d.ts +0 -12
  81. package/dist/server/actions/tasks.d.ts +0 -7
  82. package/dist/server/actions/workflow-executions.d.ts +0 -7
  83. package/dist/server/adapters/redis-lock-adapter.d.ts +0 -15
  84. package/dist/server/adapters/redis-node-registry.d.ts +0 -12
  85. package/dist/server/adapters/redis-pubsub-adapter.d.ts +0 -16
  86. package/dist/server/collections/app.d.ts +0 -8
  87. package/dist/server/collections/cluster-manager-acl-cache.d.ts +0 -22
  88. package/dist/server/collections/cluster-manager-cache-mgr.d.ts +0 -22
  89. package/dist/server/collections/cluster-manager-cluster.d.ts +0 -22
  90. package/dist/server/collections/cluster-manager-doctor-runs.d.ts +0 -3
  91. package/dist/server/collections/cluster-manager-doctor.d.ts +0 -18
  92. package/dist/server/collections/cluster-manager-lock.d.ts +0 -22
  93. package/dist/server/collections/cluster-manager-plugins.d.ts +0 -18
  94. package/dist/server/collections/cluster-manager-queue.d.ts +0 -22
  95. package/dist/server/collections/cluster-manager-redis.d.ts +0 -22
  96. package/dist/server/collections/cluster-manager-workflow.d.ts +0 -22
  97. package/dist/server/collections/cluster-manager.d.ts +0 -22
  98. package/dist/server/collections/orchestrator-settings.d.ts +0 -59
  99. package/dist/server/collections/orchestrator-stacks.d.ts +0 -102
  100. package/dist/server/collections/worker-orchestrator.d.ts +0 -22
  101. package/dist/server/collections/worker-packages-configs.d.ts +0 -3
  102. package/dist/server/collections/worker-packages.d.ts +0 -22
  103. package/dist/server/hooks/cacheInvalidationHooks.d.ts +0 -1
  104. package/dist/server/middlewares/listMetaCacheMiddleware.d.ts +0 -2
  105. package/dist/server/orchestrator/PackageManager.d.ts +0 -39
  106. package/dist/server/orchestrator/docker-adapter.d.ts +0 -41
  107. package/dist/server/orchestrator/index.d.ts +0 -4
  108. package/dist/server/orchestrator/k8s-adapter.d.ts +0 -50
  109. package/dist/server/orchestrator/leader-election.d.ts +0 -48
  110. package/dist/server/orchestrator/types.d.ts +0 -84
  111. package/dist/server/plugin.d.ts +0 -26
  112. package/dist/server/utils/node.d.ts +0 -6
  113. package/dist/server/utils/redis.d.ts +0 -29
  114. package/dist/server/utils/versionManager.d.ts +0 -10
  115. package/dist/shared/packages.d.ts +0 -23
  116. /package/{dist/server/index.d.ts → src/client-v2/index.tsx} +0 -0
@@ -35,9 +35,7 @@ function getDockerode() {
35
35
  try {
36
36
  Dockerode = require("dockerode");
37
37
  } catch {
38
- throw new Error(
39
- '[DockerAdapter] "dockerode" package not found. Install it: yarn add dockerode'
40
- );
38
+ throw new Error('[DockerAdapter] "dockerode" package not found. Install it: yarn add dockerode');
41
39
  }
42
40
  }
43
41
  return Dockerode;
@@ -71,11 +69,7 @@ class DockerAdapter {
71
69
  const containers = await this.docker.listContainers({
72
70
  all: true,
73
71
  filters: {
74
- label: [
75
- `${LABEL_STACK}=${stack.name}`,
76
- `${LABEL_MANAGED}=true`,
77
- ...this.buildLabelFilters(this.workerLabels)
78
- ]
72
+ label: [`${LABEL_STACK}=${stack.name}`, `${LABEL_MANAGED}=true`, ...this.buildLabelFilters(this.workerLabels)]
79
73
  }
80
74
  });
81
75
  return containers.map((c) => ({
@@ -100,7 +94,7 @@ class DockerAdapter {
100
94
  }
101
95
  }
102
96
  async scale(stack, replicas) {
103
- var _a, _b, _c, _d;
97
+ var _a, _b, _c, _d, _e, _f, _g;
104
98
  const current = await this.listContainers(stack);
105
99
  const running = current.filter((c) => c.status === "running");
106
100
  const diff = replicas - running.length;
@@ -112,20 +106,27 @@ class DockerAdapter {
112
106
  };
113
107
  if (diff > 0) {
114
108
  let targetNetworks = stack.networks && stack.networks.length > 0 ? stack.networks : [];
115
- let targetNetworkMode = stack.networkMode;
109
+ const targetNetworkMode = stack.networkMode;
116
110
  let targetEnvVars = this.buildEnvArray(stack.envVars);
117
111
  let targetVolumes = stack.volumes || [];
112
+ let targetImage = stack.image;
113
+ let inheritedCmd;
114
+ let inheritedEntrypoint;
118
115
  try {
119
116
  const os = require("os");
120
117
  const myContainerId = os.hostname();
121
118
  const myContainer = this.docker.getContainer(myContainerId);
122
119
  const myInfo = await myContainer.inspect();
123
- if ((_a = myInfo == null ? void 0 : myInfo.NetworkSettings) == null ? void 0 : _a.Networks) {
120
+ if (!targetImage && ((_a = myInfo == null ? void 0 : myInfo.Config) == null ? void 0 : _a.Image)) {
121
+ targetImage = myInfo.Config.Image;
122
+ console.log("[DockerAdapter] Inherited image from app container:", targetImage);
123
+ }
124
+ if ((_b = myInfo == null ? void 0 : myInfo.NetworkSettings) == null ? void 0 : _b.Networks) {
124
125
  const inheritedNetworks = Object.keys(myInfo.NetworkSettings.Networks);
125
126
  targetNetworks = Array.from(/* @__PURE__ */ new Set([...inheritedNetworks, ...targetNetworks]));
126
127
  console.log("[DockerAdapter] Inherited networks:", targetNetworks);
127
128
  }
128
- if ((_b = myInfo == null ? void 0 : myInfo.Config) == null ? void 0 : _b.Env) {
129
+ if ((_c = myInfo == null ? void 0 : myInfo.Config) == null ? void 0 : _c.Env) {
129
130
  const envDict = {};
130
131
  myInfo.Config.Env.forEach((e) => {
131
132
  const idx = e.indexOf("=");
@@ -136,10 +137,16 @@ class DockerAdapter {
136
137
  Object.assign(envDict, stack.envVars || {});
137
138
  targetEnvVars = Object.entries(envDict).map(([k, v]) => `${k}=${v}`);
138
139
  }
139
- if ((_c = myInfo == null ? void 0 : myInfo.HostConfig) == null ? void 0 : _c.Binds) {
140
+ if ((_d = myInfo == null ? void 0 : myInfo.HostConfig) == null ? void 0 : _d.Binds) {
140
141
  const inheritedBinds = myInfo.HostConfig.Binds;
141
142
  targetVolumes = Array.from(/* @__PURE__ */ new Set([...inheritedBinds, ...targetVolumes]));
142
143
  }
144
+ if (Array.isArray((_e = myInfo == null ? void 0 : myInfo.Config) == null ? void 0 : _e.Cmd) && myInfo.Config.Cmd.length > 0) {
145
+ inheritedCmd = myInfo.Config.Cmd;
146
+ }
147
+ if (Array.isArray((_f = myInfo == null ? void 0 : myInfo.Config) == null ? void 0 : _f.Entrypoint) && myInfo.Config.Entrypoint.length > 0) {
148
+ inheritedEntrypoint = myInfo.Config.Entrypoint;
149
+ }
143
150
  } catch (e) {
144
151
  console.error("[DockerAdapter] Failed to inherit container config:", e.message);
145
152
  }
@@ -147,11 +154,16 @@ class DockerAdapter {
147
154
  if (!hasLoggerBase) {
148
155
  targetEnvVars.push(`LOGGER_BASE_PATH=/app/nocobase/storage/logs/${stack.name}`);
149
156
  }
157
+ if (!targetImage) {
158
+ throw new Error(
159
+ `[DockerAdapter] No image configured for stack "${stack.name}" and the app container image could not be determined.`
160
+ );
161
+ }
150
162
  for (let i = 0; i < diff; i++) {
151
163
  const suffix = `${Date.now()}-${Math.random().toString(36).substring(2, 6)}`;
152
164
  const containerName = `${stack.name}-${suffix}`;
153
165
  const createOpts = {
154
- Image: stack.image,
166
+ Image: targetImage,
155
167
  name: containerName,
156
168
  Env: targetEnvVars,
157
169
  Labels: {
@@ -166,8 +178,15 @@ class DockerAdapter {
166
178
  };
167
179
  if (stack.command) {
168
180
  createOpts.Cmd = ["/bin/sh", "-c", stack.command];
181
+ } else {
182
+ if (inheritedEntrypoint) {
183
+ createOpts.Entrypoint = inheritedEntrypoint;
184
+ }
185
+ if (inheritedCmd) {
186
+ createOpts.Cmd = inheritedCmd;
187
+ }
169
188
  }
170
- if ((_d = stack.resourceLimits) == null ? void 0 : _d.memory) {
189
+ if ((_g = stack.resourceLimits) == null ? void 0 : _g.memory) {
171
190
  createOpts.HostConfig.Memory = this.parseMemory(stack.resourceLimits.memory);
172
191
  }
173
192
  if (targetNetworkMode) {
@@ -184,7 +203,9 @@ class DockerAdapter {
184
203
  const net = this.docker.getNetwork(targetNetworks[i2]);
185
204
  await net.connect({ Container: container.id });
186
205
  } catch (err) {
187
- console.warn(`[DockerAdapter] Failed to connect container ${container.id} to network ${targetNetworks[i2]}: ${err.message}`);
206
+ console.warn(
207
+ `[DockerAdapter] Failed to connect container ${container.id} to network ${targetNetworks[i2]}: ${err.message}`
208
+ );
188
209
  }
189
210
  }
190
211
  }
@@ -192,9 +213,7 @@ class DockerAdapter {
192
213
  result.containersCreated.push(container.id.substring(0, 12));
193
214
  }
194
215
  } else if (diff < 0) {
195
- const sorted = running.sort(
196
- (a, b) => b.createdAt.getTime() - a.createdAt.getTime()
197
- );
216
+ const sorted = running.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
198
217
  const toRemove = sorted.slice(0, Math.abs(diff));
199
218
  for (const c of toRemove) {
200
219
  try {
@@ -293,14 +312,17 @@ class DockerAdapter {
293
312
  }
294
313
  parseLabelSelector(selector) {
295
314
  if (!(selector == null ? void 0 : selector.trim())) return {};
296
- return selector.split(",").map((part) => part.trim()).filter(Boolean).reduce((acc, part) => {
297
- const [key, ...valueParts] = part.split("=");
298
- const value = valueParts.join("=");
299
- if ((key == null ? void 0 : key.trim()) && (value == null ? void 0 : value.trim())) {
300
- acc[key.trim()] = value.trim();
301
- }
302
- return acc;
303
- }, {});
315
+ return selector.split(",").map((part) => part.trim()).filter(Boolean).reduce(
316
+ (acc, part) => {
317
+ const [key, ...valueParts] = part.split("=");
318
+ const value = valueParts.join("=");
319
+ if ((key == null ? void 0 : key.trim()) && (value == null ? void 0 : value.trim())) {
320
+ acc[key.trim()] = value.trim();
321
+ }
322
+ return acc;
323
+ },
324
+ {}
325
+ );
304
326
  }
305
327
  labelsMatch(labels, expected) {
306
328
  return Object.entries(expected).every(([k, v]) => labels[k] === v);
@@ -58,6 +58,7 @@ var import_redis_node_registry = require("./adapters/redis-node-registry");
58
58
  var import_redis_lock_adapter = require("./adapters/redis-lock-adapter");
59
59
  var import_orchestrator = require("./actions/orchestrator");
60
60
  var import_plugin_operations = require("./actions/plugin-operations");
61
+ var import_queue_mappings = require("./actions/queue-mappings");
61
62
  var import_docker_adapter = require("./orchestrator/docker-adapter");
62
63
  var import_k8s_adapter = require("./orchestrator/k8s-adapter");
63
64
  var import_leader_election = require("./orchestrator/leader-election");
@@ -87,8 +88,7 @@ class PluginClusterManagerServer extends import_server.Plugin {
87
88
  this.app.on("afterStart", () => {
88
89
  var _a;
89
90
  (_a = this.nodeRegistry) == null ? void 0 : _a.start();
90
- const mode = process.env.WORKER_MODE || "main";
91
- const isWorker = mode === "worker" || mode === "task" || mode === "*" || process.env.APP_ROLE === "worker" || process.env.APP_ROLE === "sandbox";
91
+ const isWorker = (0, import_node.isWorkerMode)(process.env.WORKER_MODE) || process.env.APP_ROLE === "worker" || process.env.APP_ROLE === "sandbox";
92
92
  if (isWorker) {
93
93
  setTimeout(async () => {
94
94
  try {
@@ -141,9 +141,7 @@ class PluginClusterManagerServer extends import_server.Plugin {
141
141
  (_a = this.nodeRegistry) == null ? void 0 : _a.stop();
142
142
  });
143
143
  this.app.db.on("executions.afterSave", async (model) => {
144
- const mode = process.env.WORKER_MODE || "main";
145
- const isWorker = mode === "worker" || mode === "task" || mode === "*";
146
- if (isWorker) {
144
+ if ((0, import_node.isWorkerMode)(process.env.WORKER_MODE)) {
147
145
  const id = model.get("id");
148
146
  const redis = (0, import_redis.getRedisClient)(this.app);
149
147
  if (id && redis) {
@@ -307,6 +305,10 @@ class PluginClusterManagerServer extends import_server.Plugin {
307
305
  name: "clusterManagerPlugins",
308
306
  actions: import_plugin_operations.pluginOperationsActions
309
307
  });
308
+ this.app.resourcer.define({
309
+ name: "workerQueueMappings",
310
+ actions: import_queue_mappings.queueMappingsActions
311
+ });
310
312
  const aclCacheMiddleware = (0, import_acl_cache.createAclCacheMiddleware)(this.app);
311
313
  this.app.acl.use(aclCacheMiddleware, {
312
314
  tag: "aclCache",
@@ -345,7 +347,8 @@ class PluginClusterManagerServer extends import_server.Plugin {
345
347
  "workerOrchestrator:*",
346
348
  "orchestratorStacks:*",
347
349
  "workerPackages:*",
348
- "clusterManagerPlugins:*"
350
+ "clusterManagerPlugins:*",
351
+ "workerQueueMappings:*"
349
352
  ]
350
353
  });
351
354
  await this.initOrchestrator();
@@ -496,8 +499,7 @@ class PluginClusterManagerServer extends import_server.Plugin {
496
499
  }
497
500
  }
498
501
  isWorkerOnlyNode() {
499
- const workerMode = process.env.WORKER_MODE || "";
500
- return workerMode === "worker" || workerMode === "task" || workerMode === "*";
502
+ return (0, import_node.isWorkerMode)(process.env.WORKER_MODE);
501
503
  }
502
504
  }
503
505
  var plugin_default = PluginClusterManagerServer;
@@ -0,0 +1,141 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var queue_scanner_exports = {};
28
+ __export(queue_scanner_exports, {
29
+ scanQueues: () => scanQueues
30
+ });
31
+ module.exports = __toCommonJS(queue_scanner_exports);
32
+ var import_redis = require("./utils/redis");
33
+ const KNOWN_QUEUE_LABELS = {
34
+ "workflow:process": {
35
+ label: "Workflow",
36
+ description: "Process workflow executions (plugin-workflow)"
37
+ },
38
+ "async-task:process": {
39
+ label: "Async Tasks",
40
+ description: "Execute async tasks (plugin-async-task-manager)"
41
+ },
42
+ "knowledge-base:document-vectorize": {
43
+ label: "Document Vectorization",
44
+ description: "Vectorize knowledge base documents (plugin-knowledge-base)"
45
+ },
46
+ "git-review:process": {
47
+ label: "Git Review",
48
+ description: "AI code review jobs (plugin-git-manager)"
49
+ },
50
+ "build-guide:process": {
51
+ label: "Build Guide",
52
+ description: "Build user guide pages (plugin-build-guide-block)"
53
+ },
54
+ "build-ui-template:process": {
55
+ label: "Build UI Template",
56
+ description: "Build UI template pages (plugin-build-ui-template)"
57
+ }
58
+ };
59
+ const REDIS_QUEUE_PATTERNS = ["*:plugin-git-manager:review:queue", "*:plugin-build-guide-block:build:queue"];
60
+ function describeRedisQueueKey(key) {
61
+ const parts = String(key).split(":");
62
+ const plugin = parts[parts.length - 3] || "unknown";
63
+ const queue = parts[parts.length - 2] || key;
64
+ return {
65
+ label: `${queue} (${plugin})`,
66
+ description: `Redis List queue from ${plugin}`
67
+ };
68
+ }
69
+ function scanEventQueue(app) {
70
+ const eq = app.eventQueue;
71
+ if (!eq || !eq.events) return [];
72
+ const events = eq.events;
73
+ const items = [];
74
+ for (const [channel] of events.entries()) {
75
+ const known = KNOWN_QUEUE_LABELS[channel];
76
+ items.push({
77
+ name: channel,
78
+ label: (known == null ? void 0 : known.label) ?? channel,
79
+ description: (known == null ? void 0 : known.description) ?? `EventQueue channel: ${channel}`,
80
+ type: "event-queue",
81
+ pending: null
82
+ });
83
+ }
84
+ return items;
85
+ }
86
+ async function scanRedisQueues(app) {
87
+ var _a;
88
+ const redis = (0, import_redis.getRedisClient)(app);
89
+ if (!redis) {
90
+ return [];
91
+ }
92
+ const seen = /* @__PURE__ */ new Set();
93
+ const items = [];
94
+ for (const pattern of REDIS_QUEUE_PATTERNS) {
95
+ try {
96
+ const keys = await redis.sendCommand(["SCAN", "0", "MATCH", pattern, "COUNT", "200"]);
97
+ const keyList = typeof ((_a = keys[1]) == null ? void 0 : _a.length) === "number" ? keys[1] : [];
98
+ for (const key of keyList) {
99
+ if (seen.has(key)) continue;
100
+ seen.add(key);
101
+ const desc = describeRedisQueueKey(key);
102
+ let pending = 0;
103
+ try {
104
+ pending = Number(await redis.sendCommand(["LLEN", key])) || 0;
105
+ } catch {
106
+ pending = 0;
107
+ }
108
+ items.push({
109
+ name: key,
110
+ label: desc.label,
111
+ description: desc.description,
112
+ type: "redis-list",
113
+ pending
114
+ });
115
+ }
116
+ } catch {
117
+ }
118
+ }
119
+ return items;
120
+ }
121
+ async function scanQueues(app) {
122
+ const eventQueues = scanEventQueue(app);
123
+ const redisQueues = await scanRedisQueues(app);
124
+ const seenNames = /* @__PURE__ */ new Set();
125
+ const merged = [];
126
+ for (const q of eventQueues) {
127
+ merged.push(q);
128
+ seenNames.add(q.name);
129
+ }
130
+ for (const q of redisQueues) {
131
+ if (!seenNames.has(q.name)) {
132
+ merged.push(q);
133
+ seenNames.add(q.name);
134
+ }
135
+ }
136
+ return { queues: merged, total: merged.length };
137
+ }
138
+ // Annotate the CommonJS export names for ESM import in node:
139
+ 0 && (module.exports = {
140
+ scanQueues
141
+ });
@@ -36,10 +36,35 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
36
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
37
  var node_exports = {};
38
38
  __export(node_exports, {
39
- getLocalNodeId: () => getLocalNodeId
39
+ getLocalNodeId: () => getLocalNodeId,
40
+ getLocalRole: () => getLocalRole,
41
+ getNodeRoleFrom: () => getNodeRoleFrom,
42
+ isWorkerMode: () => isWorkerMode
40
43
  });
41
44
  module.exports = __toCommonJS(node_exports);
42
45
  var import_os = __toESM(require("os"));
46
+ function isWorkerMode(workerMode) {
47
+ const mode = (workerMode ?? process.env.WORKER_MODE ?? "").trim();
48
+ if (!mode || mode === "main" || mode === "app") return false;
49
+ if (mode === "-") return false;
50
+ const topics = mode.split(",").map((t) => t.trim()).filter(Boolean);
51
+ if (topics.includes("!")) return false;
52
+ return true;
53
+ }
54
+ function getNodeRoleFrom(opts) {
55
+ if (opts.appRole === "app" || opts.appRole === "worker" || opts.appRole === "sandbox") {
56
+ return opts.appRole;
57
+ }
58
+ if (opts.isSandbox) return "sandbox";
59
+ return isWorkerMode(opts.workerMode) ? "worker" : "app";
60
+ }
61
+ function getLocalRole() {
62
+ return getNodeRoleFrom({
63
+ workerMode: process.env.WORKER_MODE,
64
+ appRole: process.env.APP_ROLE,
65
+ isSandbox: process.env.SKILL_HUB_SANDBOX === "true"
66
+ });
67
+ }
43
68
  function getLocalNodeId(app) {
44
69
  const port = process.env.APP_PORT || "unknown";
45
70
  const mode = process.env.WORKER_MODE || "main";
@@ -48,5 +73,8 @@ function getLocalNodeId(app) {
48
73
  }
49
74
  // Annotate the CommonJS export names for ESM import in node:
50
75
  0 && (module.exports = {
51
- getLocalNodeId
76
+ getLocalNodeId,
77
+ getLocalRole,
78
+ getNodeRoleFrom,
79
+ isWorkerMode
52
80
  });
package/package.json CHANGED
@@ -1,42 +1,46 @@
1
- {
2
- "name": "plugin-cluster-manager",
3
- "displayName": "Cluster Manager",
4
- "displayName.zh-CN": "Cluster Manager",
5
- "description": "Cluster node tracking, task orchestration, worker management, and package distribution",
6
- "version": "1.1.11",
7
- "license": "Apache-2.0",
8
- "main": "./dist/server/index.js",
9
- "keywords": [
10
- "Monitoring",
11
- "DevOps"
12
- ],
13
- "files": [
14
- "dist",
15
- "src",
16
- "client.js",
17
- "server.js",
18
- "client.d.ts",
19
- "server.d.ts"
20
- ],
21
- "peerDependencies": {
22
- "@nocobase/client": "2.x",
23
- "@nocobase/server": "2.x",
24
- "@nocobase/database": "2.x"
25
- },
26
- "dependencies": {
27
- "@nocobase/lock-manager": "2.x"
28
- },
29
- "devDependencies": {
30
- "@kubernetes/client-node": "^0.22.3",
31
- "dockerode": "^3.3.5",
32
- "redis": "^5.10.0",
33
- "redlock": "5.0.0-beta.2",
34
- "uuid": "^9.0.1"
35
- },
36
- "nocobase": {
37
- "supportedVersions": [
38
- "2.x"
39
- ],
40
- "editionLevel": 0
41
- }
42
- }
1
+ {
2
+ "name": "plugin-cluster-manager",
3
+ "displayName": "Cluster Manager",
4
+ "displayName.zh-CN": "Cluster Manager",
5
+ "description": "Cluster node tracking, task orchestration, worker management, and package distribution",
6
+ "version": "1.1.15",
7
+ "license": "Apache-2.0",
8
+ "main": "dist/server/index.js",
9
+ "keywords": [
10
+ "Monitoring",
11
+ "DevOps"
12
+ ],
13
+ "files": [
14
+ "dist",
15
+ "src",
16
+ "client.js",
17
+ "server.js",
18
+ "client.d.ts",
19
+ "server.d.ts",
20
+ "client-v2.js",
21
+ "client-v2.d.ts"
22
+ ],
23
+ "peerDependencies": {
24
+ "@nocobase/client": "2.x",
25
+ "@nocobase/server": "2.x",
26
+ "@nocobase/database": "2.x",
27
+ "@nocobase/client-v2": "2.x",
28
+ "@nocobase/flow-engine": "2.x"
29
+ },
30
+ "dependencies": {
31
+ "@nocobase/lock-manager": "2.x"
32
+ },
33
+ "devDependencies": {
34
+ "@kubernetes/client-node": "^0.22.3",
35
+ "dockerode": "^3.3.5",
36
+ "redis": "^5.10.0",
37
+ "redlock": "5.0.0-beta.2",
38
+ "uuid": "^9.0.1"
39
+ },
40
+ "nocobase": {
41
+ "supportedVersions": [
42
+ "2.x"
43
+ ],
44
+ "editionLevel": 0
45
+ }
46
+ }