@camstack/server 1.2.458 → 1.2.459

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.
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.AgentUpdateService = exports.AGENT_RESTART_GRACE_MS = exports.AGENT_RUNTIME_ADDON_ID = void 0;
36
+ exports.AgentUpdateService = exports.AgentRestartAnnouncer = exports.AGENT_RESTART_GRACE_MS = exports.AGENT_RUNTIME_ADDON_ID = void 0;
37
37
  exports.isRunningInContainer = isRunningInContainer;
38
38
  exports.resolveAgentPackageJsonPath = resolveAgentPackageJsonPath;
39
39
  exports.scheduleAgentRestart = scheduleAgentRestart;
@@ -149,7 +149,61 @@ function scheduleAgentRestart(logger, requestedBy, dataDir) {
149
149
  }, exports.AGENT_RESTART_GRACE_MS);
150
150
  grace.unref();
151
151
  }
152
+ /**
153
+ * The agent's restart ANNOUNCEMENT (D723): `system.restarting`, emitted before
154
+ * the self-SIGTERM, through the agent's event bus — which broadcasts it to the
155
+ * hub, where the notification centre turns it into `node-restarting` or
156
+ * `node-updating`. Until D723 the agent emitted nothing before exiting, so an
157
+ * agent's restart was announced only after the fact (`system.restart-completed`).
158
+ *
159
+ * Its own small object because the restart seam is a closure handed to the base
160
+ * class BEFORE `this` exists, while the bus is bound later (`bindAvailability`,
161
+ * once the mesh is up). A restart before that has nobody to tell — said, never
162
+ * silent.
163
+ */
164
+ class AgentRestartAnnouncer {
165
+ logger;
166
+ eventBus;
167
+ nodeId;
168
+ constructor(logger, eventBus, nodeId) {
169
+ this.logger = logger;
170
+ this.eventBus = eventBus;
171
+ this.nodeId = nodeId;
172
+ }
173
+ bind(eventBus, nodeId) {
174
+ this.eventBus = eventBus;
175
+ this.nodeId = nodeId;
176
+ }
177
+ announce(marker) {
178
+ const bus = this.eventBus;
179
+ if (bus === null) {
180
+ this.logger.warn('agent restart NOT announced — the event bus is not bound yet', {
181
+ meta: { nodeId: this.nodeId, kind: marker.kind },
182
+ });
183
+ return;
184
+ }
185
+ const payload = { ...marker, nodeId: this.nodeId };
186
+ try {
187
+ bus.emit({
188
+ id: (0, node_crypto_1.randomUUID)(),
189
+ timestamp: new Date(),
190
+ source: { type: 'core', id: 'agent-update-service' },
191
+ category: types_1.EventCategory.SystemRestarting,
192
+ data: payload,
193
+ });
194
+ }
195
+ catch (err) {
196
+ // Telemetry (D8): an announcement that could not go out must never block
197
+ // the restart it announces.
198
+ this.logger.warn('agent restart announcement failed', {
199
+ meta: { nodeId: this.nodeId, error: err instanceof Error ? err.message : String(err) },
200
+ });
201
+ }
202
+ }
203
+ }
204
+ exports.AgentRestartAnnouncer = AgentRestartAnnouncer;
152
205
  class AgentUpdateService extends index_js_1.RootUpdateService {
206
+ restartAnnouncer;
153
207
  updateAvailability;
154
208
  eventBus;
155
209
  nodeId;
@@ -164,6 +218,7 @@ class AgentUpdateService extends index_js_1.RootUpdateService {
164
218
  // handshake settles the id; the log tag keeps the boot-time value, which is
165
219
  // the same string in every deployment that sets `CAMSTACK_NODE_ID`.
166
220
  const nodeId = options.nodeId ?? process.env['CAMSTACK_NODE_ID'] ?? 'agent';
221
+ const restartAnnouncer = new AgentRestartAnnouncer(options.logger, options.eventBus ?? null, nodeId);
167
222
  super({
168
223
  spec: index_js_1.HUB_ROOT_SPEC,
169
224
  nodeId,
@@ -177,7 +232,8 @@ class AgentUpdateService extends index_js_1.RootUpdateService {
177
232
  },
178
233
  logger: options.logger,
179
234
  restartServer: (requestedBy, update) => {
180
- writeAgentRestartMarker(options.dataDir, requestedBy, update);
235
+ const marker = writeAgentRestartMarker(options.dataDir, requestedBy, update);
236
+ restartAnnouncer.announce(marker);
181
237
  restartAgent(requestedBy);
182
238
  },
183
239
  dataDir: options.dataDir,
@@ -204,6 +260,7 @@ class AgentUpdateService extends index_js_1.RootUpdateService {
204
260
  now: options.now,
205
261
  });
206
262
  this.nodeId = nodeId;
263
+ this.restartAnnouncer = restartAnnouncer;
207
264
  this.agentDataDir = options.dataDir;
208
265
  this.agentLogger = options.logger;
209
266
  this.eventBus = options.eventBus ?? null;
@@ -220,6 +277,7 @@ class AgentUpdateService extends index_js_1.RootUpdateService {
220
277
  bindAvailability(eventBus, nodeId) {
221
278
  this.eventBus = eventBus;
222
279
  this.nodeId = nodeId;
280
+ this.restartAnnouncer.bind(eventBus, nodeId);
223
281
  this.updateAvailability = new update_availability_emitter_js_1.UpdateAvailabilityEmitter(eventBus, { type: 'core', id: 'agent-update-service' }, new update_availability_store_js_1.FileUpdateAvailabilityStore(this.agentDataDir, 'agent-update', this.agentLogger));
224
282
  }
225
283
  async checkServerUpdate() {
@@ -266,19 +324,22 @@ class AgentUpdateService extends index_js_1.RootUpdateService {
266
324
  }
267
325
  }
268
326
  exports.AgentUpdateService = AgentUpdateService;
327
+ /** Write the marker and return it — the same payload is the announcement (D723). */
269
328
  function writeAgentRestartMarker(dataDir, requestedBy, update) {
329
+ // Same builder as the hub: an agent's "Server aggiornato" notification must
330
+ // name both versions too — see `core/updates/restart-marker.ts`.
331
+ const marker = (0, restart_marker_js_1.buildRestartMarker)({
332
+ requestedAt: Date.now(),
333
+ requestedBy,
334
+ ...(update !== undefined ? { update } : {}),
335
+ });
270
336
  try {
271
- // Same builder as the hub: an agent's "Server aggiornato" notification must
272
- // name both versions too — see `core/updates/restart-marker.ts`.
273
- (0, system_1.writePendingRestart)(dataDir, (0, restart_marker_js_1.buildRestartMarker)({
274
- requestedAt: Date.now(),
275
- requestedBy,
276
- ...(update !== undefined ? { update } : {}),
277
- }));
337
+ (0, system_1.writePendingRestart)(dataDir, marker);
278
338
  }
279
339
  catch {
280
340
  // Marker write must never block the restart.
281
341
  }
342
+ return marker;
282
343
  }
283
344
  /**
284
345
  * The manifest entry for the agent runtime's own providers. Appended to
@@ -1146,7 +1146,11 @@ class AddonPackageService {
1146
1146
  timestamp: new Date(),
1147
1147
  source: { type: 'core', id: 'addon-package-service' },
1148
1148
  category: types_1.EventCategory.SystemRestarting,
1149
- data: payload,
1149
+ // The node, as `system.restart-completed` names it after the boot
1150
+ // (`post-boot.service.ts`): the announcement and the landing of one
1151
+ // restart must name the same node, or a stale `node-updating` could not
1152
+ // be matched to the `server-updated` that supersedes it (D723).
1153
+ data: { ...payload, nodeId: process.env['CAMSTACK_NODE_ID'] ?? 'hub' },
1150
1154
  });
1151
1155
  // 10s grace gives in-flight requests time to drain.
1152
1156
  (0, system_1.scheduleSelfRestart)({ delayMs: 10_000 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/server",
3
- "version": "1.2.458",
3
+ "version": "1.2.459",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "files": [
@@ -37,17 +37,17 @@
37
37
  ]
38
38
  },
39
39
  "dependencies": {
40
- "@camstack/addon-admin-ui": "1.2.332",
40
+ "@camstack/addon-admin-ui": "1.2.333",
41
41
  "@camstack/addon-agent-ui": "1.2.175",
42
42
  "@camstack/addon-auth": "1.2.127",
43
43
  "@camstack/addon-decoder-nodeav": "1.2.119",
44
44
  "@camstack/addon-notifiers": "1.2.128",
45
45
  "@camstack/addon-pipeline": "1.2.328",
46
46
  "@camstack/addon-pipeline-orchestrator": "1.2.283",
47
- "@camstack/addon-post-analysis": "1.2.334",
47
+ "@camstack/addon-post-analysis": "1.2.335",
48
48
  "@camstack/sdk": "1.2.122",
49
- "@camstack/system": "1.2.355",
50
- "@camstack/types": "1.2.306",
49
+ "@camstack/system": "1.2.356",
50
+ "@camstack/types": "1.2.307",
51
51
  "@camstack/ui-library": "1.2.233",
52
52
  "@fastify/compress": "^9.0.0",
53
53
  "@fastify/cookie": "^11.0.2",