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
@@ -122,6 +122,10 @@ const orchestratorActions = {
122
122
  * POST /workerOrchestrator:scale
123
123
  * Body: { stackId: 1, replicas: 3 }
124
124
  * Leader-only
125
+ *
126
+ * Before scaling, resolves queue-to-stack mappings and injects
127
+ * WORKER_MODE into the stack's envVars so new containers only
128
+ * process assigned queues.
125
129
  */
126
130
  async scale(ctx, next) {
127
131
  assertLeader(ctx);
@@ -130,6 +134,39 @@ const orchestratorActions = {
130
134
  if (replicas === void 0 || replicas === null) ctx.throw(400, "replicas is required");
131
135
  if (replicas < 0 || replicas > 20) ctx.throw(400, "replicas must be between 0 and 20");
132
136
  const stack = await getStack(ctx, stackId);
137
+ try {
138
+ const mappingsRepo = ctx.db.getRepository("workerQueueMappings");
139
+ if (mappingsRepo) {
140
+ const assigned = await mappingsRepo.find({
141
+ filter: {
142
+ stackId: stack.id,
143
+ enabled: true
144
+ }
145
+ });
146
+ const queueNames = assigned.map((m) => m.get("queueName")).filter(Boolean);
147
+ if (queueNames.length > 0) {
148
+ const workerMode = queueNames.join(",");
149
+ ctx.app.logger.info(
150
+ `[Orchestrator] Injecting WORKER_MODE=${workerMode} for stack "${stack.name}" (${queueNames.length} queue(s) assigned)`
151
+ );
152
+ stack.envVars = {
153
+ ...stack.envVars || {},
154
+ WORKER_MODE: workerMode
155
+ };
156
+ } else {
157
+ stack.envVars = {
158
+ ...stack.envVars || {},
159
+ WORKER_MODE: "*"
160
+ };
161
+ }
162
+ }
163
+ } catch (err) {
164
+ ctx.app.logger.debug(`[Orchestrator] Queue mappings not available: ${err.message}`);
165
+ stack.envVars = {
166
+ ...stack.envVars || {},
167
+ WORKER_MODE: "*"
168
+ };
169
+ }
133
170
  const result = await adapter.scale(stack, Number(replicas));
134
171
  const repo = ctx.db.getRepository("orchestratorStacks");
135
172
  await repo.update({
@@ -0,0 +1,107 @@
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_mappings_exports = {};
28
+ __export(queue_mappings_exports, {
29
+ queueMappingsActions: () => queueMappingsActions
30
+ });
31
+ module.exports = __toCommonJS(queue_mappings_exports);
32
+ var import_queue_scanner = require("../queue-scanner");
33
+ const queueMappingsActions = {
34
+ /**
35
+ * GET /workerQueueMappings:scanQueues
36
+ * Scans all registered queues (EventQueue + Redis) and merges with existing mappings.
37
+ */
38
+ async scanQueues(ctx, next) {
39
+ const result = await (0, import_queue_scanner.scanQueues)(ctx.app);
40
+ const repo = ctx.db.getRepository("workerQueueMappings");
41
+ let existingMappings = [];
42
+ try {
43
+ existingMappings = await repo.find();
44
+ } catch {
45
+ }
46
+ const mappedNames = new Set(existingMappings.map((m) => m.get("queueName")));
47
+ ctx.body = {
48
+ discovered: result.queues,
49
+ total: result.total,
50
+ registered: existingMappings.map((m) => ({
51
+ id: m.get("id"),
52
+ queueName: m.get("queueName"),
53
+ label: m.get("label"),
54
+ stackId: m.get("stackId"),
55
+ enabled: m.get("enabled"),
56
+ type: m.get("type")
57
+ })),
58
+ unmapped: result.queues.filter((q) => !mappedNames.has(q.name)).map((q) => ({
59
+ name: q.name,
60
+ type: q.type,
61
+ label: q.label,
62
+ description: q.description
63
+ }))
64
+ };
65
+ await next();
66
+ },
67
+ /**
68
+ * POST /workerQueueMappings:autoMap
69
+ * Auto-create mappings for any discovered queues that don't have one yet.
70
+ * Body: { stackId?: number } — optional default stack for new mappings
71
+ */
72
+ async autoMap(ctx, next) {
73
+ const { stackId } = ctx.action.params.values || {};
74
+ const result = await (0, import_queue_scanner.scanQueues)(ctx.app);
75
+ const repo = ctx.db.getRepository("workerQueueMappings");
76
+ let existingMappings = [];
77
+ try {
78
+ existingMappings = await repo.find();
79
+ } catch {
80
+ }
81
+ const mappedNames = new Set(existingMappings.map((m) => m.get("queueName")));
82
+ const created = [];
83
+ for (const q of result.queues) {
84
+ if (mappedNames.has(q.name)) continue;
85
+ await repo.create({
86
+ values: {
87
+ queueName: q.name,
88
+ label: q.label,
89
+ description: q.description,
90
+ type: q.type,
91
+ stackId: stackId || null,
92
+ enabled: true
93
+ }
94
+ });
95
+ created.push(q.name);
96
+ }
97
+ ctx.body = {
98
+ created,
99
+ count: created.length
100
+ };
101
+ await next();
102
+ }
103
+ };
104
+ // Annotate the CommonJS export names for ESM import in node:
105
+ 0 && (module.exports = {
106
+ queueMappingsActions
107
+ });
@@ -0,0 +1,52 @@
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 cluster_manager_doctor_runs_exports = {};
28
+ __export(cluster_manager_doctor_runs_exports, {
29
+ default: () => cluster_manager_doctor_runs_default
30
+ });
31
+ module.exports = __toCommonJS(cluster_manager_doctor_runs_exports);
32
+ var cluster_manager_doctor_runs_default = {
33
+ name: "clusterManagerDoctorRuns",
34
+ title: "Cluster Manager Doctor Runs",
35
+ fields: [
36
+ { name: "id", type: "bigInt", autoIncrement: true, primaryKey: true },
37
+ { name: "runId", type: "string", length: 64, unique: true, allowNull: false },
38
+ { name: "status", type: "string", length: 20, defaultValue: "running", allowNull: false },
39
+ { name: "durationMs", type: "integer", defaultValue: 12e4, allowNull: false },
40
+ { name: "progress", type: "integer", defaultValue: 0, allowNull: false },
41
+ { name: "startedAt", type: "date", allowNull: false },
42
+ { name: "deadlineAt", type: "date", allowNull: false },
43
+ { name: "finishedAt", type: "date", allowNull: true },
44
+ { name: "finishReason", type: "string", length: 40, allowNull: true },
45
+ { name: "startedBy", type: "string", length: 200, allowNull: true },
46
+ { name: "summary", type: "json", allowNull: true },
47
+ { name: "report", type: "json", allowNull: true },
48
+ { name: "error", type: "text", allowNull: true },
49
+ { name: "createdAt", type: "date" },
50
+ { name: "updatedAt", type: "date" }
51
+ ]
52
+ };
@@ -0,0 +1,44 @@
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 cluster_manager_doctor_exports = {};
28
+ __export(cluster_manager_doctor_exports, {
29
+ default: () => cluster_manager_doctor_default
30
+ });
31
+ module.exports = __toCommonJS(cluster_manager_doctor_exports);
32
+ var cluster_manager_doctor_default = {
33
+ name: "clusterManagerDoctor",
34
+ dumpRules: "skip",
35
+ autoGenId: true,
36
+ createdAt: false,
37
+ updatedAt: false,
38
+ fields: [
39
+ {
40
+ name: "name",
41
+ type: "string"
42
+ }
43
+ ]
44
+ };
@@ -0,0 +1,106 @@
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 worker_queue_mappings_exports = {};
28
+ __export(worker_queue_mappings_exports, {
29
+ default: () => worker_queue_mappings_default
30
+ });
31
+ module.exports = __toCommonJS(worker_queue_mappings_exports);
32
+ var worker_queue_mappings_default = {
33
+ name: "workerQueueMappings",
34
+ autoGenId: true,
35
+ createdAt: true,
36
+ updatedAt: true,
37
+ fields: [
38
+ {
39
+ name: "queueName",
40
+ type: "string",
41
+ unique: true,
42
+ interface: "input",
43
+ uiSchema: {
44
+ title: "Queue Name",
45
+ "x-component": "Input",
46
+ required: true
47
+ }
48
+ },
49
+ {
50
+ name: "label",
51
+ type: "string",
52
+ interface: "input",
53
+ uiSchema: {
54
+ title: "Label",
55
+ "x-component": "Input",
56
+ description: "Human-readable display name"
57
+ }
58
+ },
59
+ {
60
+ name: "description",
61
+ type: "text",
62
+ interface: "textarea",
63
+ uiSchema: {
64
+ title: "Description",
65
+ "x-component": "Input.TextArea"
66
+ }
67
+ },
68
+ {
69
+ name: "type",
70
+ type: "string",
71
+ interface: "select",
72
+ defaultValue: "event-queue",
73
+ uiSchema: {
74
+ title: "Source Type",
75
+ "x-component": "Select",
76
+ enum: [
77
+ { value: "event-queue", label: "EventQueue" },
78
+ { value: "redis-list", label: "Redis List" }
79
+ ]
80
+ }
81
+ },
82
+ {
83
+ name: "stackId",
84
+ type: "integer",
85
+ interface: "select",
86
+ uiSchema: {
87
+ title: "Assigned Stack",
88
+ "x-component": "Select",
89
+ "x-component-props": {
90
+ allowClear: true,
91
+ placeholder: "Unassigned (worker runs all queues)"
92
+ }
93
+ }
94
+ },
95
+ {
96
+ name: "enabled",
97
+ type: "boolean",
98
+ defaultValue: true,
99
+ interface: "checkbox",
100
+ uiSchema: {
101
+ title: "Enabled",
102
+ "x-component": "Checkbox"
103
+ }
104
+ }
105
+ ]
106
+ };
@@ -0,0 +1,81 @@
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 cacheInvalidationHooks_exports = {};
28
+ __export(cacheInvalidationHooks_exports, {
29
+ registerCacheHooks: () => registerCacheHooks
30
+ });
31
+ module.exports = __toCommonJS(cacheInvalidationHooks_exports);
32
+ var import_versionManager = require("../utils/versionManager");
33
+ function registerCacheHooks(app) {
34
+ const db = app.db;
35
+ db.on("collections.afterSave", async () => {
36
+ await import_versionManager.cacheVersionManager.incrementCollectionVersion(app);
37
+ });
38
+ db.on("collections.afterDestroy", async () => {
39
+ await import_versionManager.cacheVersionManager.incrementCollectionVersion(app);
40
+ });
41
+ db.on("fields.afterSave", async () => {
42
+ await import_versionManager.cacheVersionManager.incrementCollectionVersion(app);
43
+ });
44
+ db.on("fields.afterDestroy", async () => {
45
+ await import_versionManager.cacheVersionManager.incrementCollectionVersion(app);
46
+ });
47
+ db.on("uiSchemas.afterSave", async () => {
48
+ await import_versionManager.cacheVersionManager.incrementSchemaVersion(app);
49
+ });
50
+ db.on("uiSchemas.afterDestroy", async () => {
51
+ await import_versionManager.cacheVersionManager.incrementSchemaVersion(app);
52
+ });
53
+ const invalidateRole = async (model) => {
54
+ var _a, _b;
55
+ const roleName = ((_a = model.get) == null ? void 0 : _a.call(model, "roleName")) || ((_b = model.get) == null ? void 0 : _b.call(model, "name"));
56
+ if (roleName) {
57
+ await import_versionManager.cacheVersionManager.incrementAclVersion(app, roleName);
58
+ } else {
59
+ await import_versionManager.cacheVersionManager.incrementAllAclVersions(app);
60
+ }
61
+ };
62
+ db.on("roles.afterSave", invalidateRole);
63
+ db.on("roles.afterDestroy", invalidateRole);
64
+ db.on("rolesResources.afterSave", invalidateRole);
65
+ db.on("rolesResources.afterDestroy", invalidateRole);
66
+ db.on("rolesResourcesActions.afterSave", invalidateRole);
67
+ db.on("rolesResourcesActions.afterDestroy", invalidateRole);
68
+ db.on("rolesUsers.afterSave", invalidateRole);
69
+ db.on("rolesUsers.afterDestroy", invalidateRole);
70
+ db.on("scopes.afterSave", async () => {
71
+ await import_versionManager.cacheVersionManager.incrementAllAclVersions(app);
72
+ });
73
+ db.on("scopes.afterDestroy", async () => {
74
+ await import_versionManager.cacheVersionManager.incrementAllAclVersions(app);
75
+ });
76
+ app.logger.info("[ClusterManager] Cache invalidation hooks registered successfully");
77
+ }
78
+ // Annotate the CommonJS export names for ESM import in node:
79
+ 0 && (module.exports = {
80
+ registerCacheHooks
81
+ });
@@ -0,0 +1,79 @@
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 listMetaCacheMiddleware_exports = {};
28
+ __export(listMetaCacheMiddleware_exports, {
29
+ createListMetaCacheMiddleware: () => createListMetaCacheMiddleware
30
+ });
31
+ module.exports = __toCommonJS(listMetaCacheMiddleware_exports);
32
+ var import_versionManager = require("../utils/versionManager");
33
+ const LIST_META_CACHE_TTL = 1e3 * 60 * 10;
34
+ function getErrorMessage(error) {
35
+ return error instanceof Error ? error.message : String(error);
36
+ }
37
+ function createListMetaCacheMiddleware(app) {
38
+ return async function listMetaCacheMiddleware(ctx, next) {
39
+ var _a, _b, _c, _d, _e, _f, _g;
40
+ const cache = app.cache;
41
+ if (!cache || ((_a = ctx.action) == null ? void 0 : _a.resourceName) !== "collections" || ((_b = ctx.action) == null ? void 0 : _b.actionName) !== "listMeta") {
42
+ return next();
43
+ }
44
+ const currentRole = ((_c = ctx.state) == null ? void 0 : _c.currentRole) || "anonymous";
45
+ const appName = ctx.headers["x-app"] || "main";
46
+ const dataSource = ctx.headers["x-data-source"] || "main";
47
+ const locale = ctx.headers["x-locale"] || ctx.headers["accept-language"] || "en-US";
48
+ let cacheKey = "";
49
+ let version = 0;
50
+ try {
51
+ version = await import_versionManager.cacheVersionManager.getCollectionVersion(app);
52
+ cacheKey = `nb:cache:${appName}:meta:v${version}:ds:${dataSource}:role:${currentRole}:lang:${locale}`;
53
+ const cached = await cache.get(cacheKey);
54
+ if (cached !== void 0 && cached !== null) {
55
+ ctx.body = typeof cached === "string" ? JSON.parse(cached) : cached;
56
+ (_d = ctx.set) == null ? void 0 : _d.call(ctx, "X-Cache", "HIT");
57
+ (_e = ctx.set) == null ? void 0 : _e.call(ctx, "X-Collection-Version", String(version));
58
+ return;
59
+ }
60
+ } catch (err) {
61
+ app.logger.warn(`[ClusterManager] listMeta cache read skipped: ${getErrorMessage(err)}`);
62
+ }
63
+ await next();
64
+ if (ctx.status === 200 && ctx.body && cacheKey) {
65
+ try {
66
+ const valueToCache = typeof ctx.body === "string" ? ctx.body : JSON.stringify(ctx.body);
67
+ await cache.set(cacheKey, valueToCache, LIST_META_CACHE_TTL);
68
+ (_f = ctx.set) == null ? void 0 : _f.call(ctx, "X-Cache", "MISS");
69
+ (_g = ctx.set) == null ? void 0 : _g.call(ctx, "X-Collection-Version", String(version));
70
+ } catch (err) {
71
+ app.logger.warn(`[ClusterManager] listMeta cache write skipped: ${getErrorMessage(err)}`);
72
+ }
73
+ }
74
+ };
75
+ }
76
+ // Annotate the CommonJS export names for ESM import in node:
77
+ 0 && (module.exports = {
78
+ createListMetaCacheMiddleware
79
+ });
@@ -41,6 +41,7 @@ __export(PackageManager_exports, {
41
41
  module.exports = __toCommonJS(PackageManager_exports);
42
42
  var import_child_process = require("child_process");
43
43
  var import_redis = require("../utils/redis");
44
+ var import_node = require("../utils/node");
44
45
  var import_fs = require("fs");
45
46
  var import_path = __toESM(require("path"));
46
47
  const SAFE_PKG_RE = /^(?:[a-zA-Z0-9_.@/-]|\[|\])+$/;
@@ -84,14 +85,7 @@ function redactUrl(value) {
84
85
  }
85
86
  }
86
87
  function getCurrentRole() {
87
- if (process.env.APP_ROLE === "app" || process.env.APP_ROLE === "worker" || process.env.APP_ROLE === "sandbox") {
88
- return process.env.APP_ROLE;
89
- }
90
- if (process.env.SKILL_HUB_SANDBOX === "true") {
91
- return "sandbox";
92
- }
93
- const workerMode = process.env.WORKER_MODE || "main";
94
- return workerMode === "worker" || workerMode === "task" || workerMode === "*" ? "worker" : "app";
88
+ return (0, import_node.getLocalRole)();
95
89
  }
96
90
  function formatCommand(command, args) {
97
91
  return [command, ...args].map((part) => {
@@ -408,22 +402,25 @@ ${logs.join("\n")}`);
408
402
  const redisClient = (0, import_redis.getRedisClient)(this.app);
409
403
  const podName = process.env.POD_NAME || require("os").hostname();
410
404
  if (redisClient) {
411
- const key = `orchestrator:pkg-status:${podName}`;
412
- await redisClient.sendCommand([
413
- "SET",
414
- key,
415
- JSON.stringify({
416
- initStatus,
417
- initProgressPercent,
418
- initProgressLog,
419
- lastInitAt: /* @__PURE__ */ new Date(),
420
- lastInitLog: logs.join("\n"),
421
- ...extraValues
422
- }),
423
- "EX",
424
- "86400"
425
- // expire after 1 day
426
- ]);
405
+ const statusPayload = JSON.stringify({
406
+ initStatus,
407
+ initProgressPercent,
408
+ initProgressLog,
409
+ lastInitAt: /* @__PURE__ */ new Date(),
410
+ lastInitLog: logs.join("\n"),
411
+ ...extraValues
412
+ });
413
+ const keys = [`orchestrator:pkg-status:${podName}`, `cluster-manager:pkg-status:${(0, import_node.getLocalNodeId)(this.app)}`];
414
+ for (const key of keys) {
415
+ await redisClient.sendCommand([
416
+ "SET",
417
+ key,
418
+ statusPayload,
419
+ "EX",
420
+ "86400"
421
+ // expire after 1 day
422
+ ]);
423
+ }
427
424
  }
428
425
  const repo = this.app.db.getRepository("workerPackagesConfigs");
429
426
  let config = await repo.findOne();