Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export class SoftwareUpdateManager extends Behavior {
await this.internal.otaService.construction;

this.reactTo(rootNode.lifecycle.online, this.#nodeOnline);
Comment thread
Apollon77 marked this conversation as resolved.
this.reactTo(rootNode.lifecycle.goingOffline, this.#nodeGoingOffline);
if (rootNode.lifecycle.isOnline) {
await this.#nodeOnline();
}
Comment thread
Apollon77 marked this conversation as resolved.
Expand All @@ -174,6 +175,7 @@ export class SoftwareUpdateManager extends Behavior {
}

async #nodeOnline() {
this.internal.suppressUpdates = false;
if (this.internal.announcements !== undefined) {
await this.internal.announcements.close();
this.internal.announcements = undefined;
Expand Down Expand Up @@ -204,6 +206,16 @@ export class SoftwareUpdateManager extends Behavior {
).start();
}

async #nodeGoingOffline() {
this.internal.suppressUpdates = true;
this.internal.checkForUpdateTimer?.stop();

// Announcements run on their own timers and write to peers, so the suppression flag alone does not stop them.
// #nodeOnline installs a fresh instance.
await this.internal.announcements?.close();
this.internal.announcements = undefined;
}

#updateAnnouncementSettings() {
if (this.internal.announcements === undefined) {
return;
Expand Down Expand Up @@ -481,7 +493,7 @@ export class SoftwareUpdateManager extends Behavior {
// Collect all client nodes and their versions, so we only need to check each version once
const updateDetails = new Map<string, CollectedNodesUpdateInfo>();
for (const peer of rootNode.peers) {
if (this.internal.closed) {
if (this.internal.suppressUpdates) {
return [];
}
if (peerToCheck !== undefined && peerToCheck !== peer) {
Expand Down Expand Up @@ -512,7 +524,7 @@ export class SoftwareUpdateManager extends Behavior {

const peersWithUpdates = new Array<{ peerAddress: PeerAddress; info: SoftwareUpdateInfo }>();
for (const infos of updateDetails.values()) {
if (this.internal.closed) {
if (this.internal.suppressUpdates) {
return [];
}
try {
Expand Down Expand Up @@ -550,7 +562,7 @@ export class SoftwareUpdateManager extends Behavior {
includeStoredUpdates,
isProduction: this.state.allowTestOtaImages ? undefined : true,
});
if (!updateDetails || this.internal.closed) {
if (!updateDetails || this.internal.suppressUpdates) {
return [];
}
const fd = await this.internal.otaService.downloadUpdate(updateDetails);
Expand Down Expand Up @@ -589,7 +601,7 @@ export class SoftwareUpdateManager extends Behavior {
consent.peerAddress.fabricIndex === peerAddress.fabricIndex &&
consent.peerAddress.nodeId === peerAddress.nodeId,
);
if (this.internal.closed) {
if (this.internal.suppressUpdates) {
break;
}
if (hasConsent) {
Expand Down Expand Up @@ -791,7 +803,7 @@ export class SoftwareUpdateManager extends Behavior {
* monitor for stalled updates.
*/
#triggerQueuedUpdate() {
if (this.internal.closed) {
if (this.internal.suppressUpdates) {
return;
}
const now = Time.nowMs;
Expand Down Expand Up @@ -850,7 +862,7 @@ export class SoftwareUpdateManager extends Behavior {
* The node usually calls queryImage as a result of this when it processes the announcement.
*/
async #triggerUpdateOnNode(entry: UpdateQueueEntry) {
if (this.internal.announcements == undefined) {
if (this.internal.announcements === undefined) {
logger.info(`Not yet initialized with peers, can not trigger update on node`, entry.peerAddress);
return;
}
Expand Down Expand Up @@ -1082,7 +1094,7 @@ export class SoftwareUpdateManager extends Behavior {
* messages, and triggers the necessary events.
*/
onOtaStatusChange(peerAddress: PeerAddress, status: OtaUpdateStatus, toVersion?: number) {
if (this.internal.closed) {
if (this.internal.suppressUpdates) {
// A post-dispose Applying would otherwise re-arm the already-disposed armer whose observers are
// closed, leaving an entry that never gets a grace timer nor self-cleans.
return;
Expand Down Expand Up @@ -1145,7 +1157,7 @@ export class SoftwareUpdateManager extends Behavior {
}

override async [Symbol.asyncDispose]() {
this.internal.closed = true;
this.internal.suppressUpdates = true;
this.internal.checkForUpdateTimer?.stop();
this.internal.updateQueueTimer?.stop();
await this.internal.announcements?.close();
Expand Down Expand Up @@ -1200,7 +1212,8 @@ export namespace SoftwareUpdateManager {

rebootResubscribeArmer?: RebootResubscribeArmer;

closed = false;
/** Raised whenever the node is not online, so update work cannot start before the first online transition. */
suppressUpdates = true;
}

export class Events extends EventEmitter {
Expand Down
Loading