Skip to content

Commit 793dfe5

Browse files
committed
perf: signal readiness before running post-connect initialization work
handleAllConnected previously did its post-connect initialization work (auto-discover networks, queue initial getall, set up periodic timers, construct + trigger HA Discovery) and THEN signaled readiness at the end. The auto-discovery step alone can take up to 5s (it has a 5s timeout waiting for the tree command response). So users with autoDiscoverNetworks enabled (the default) saw a 5s gap between connections coming up and the bridge advertising itself as ready, even though all the connection-level prerequisites were already satisfied. Moves the readiness signal to fire as soon as connection health is confirmed. The rest of the post-connect work runs after, in the same async chain - the production caller (cgateWebBridge#_handleAllConnected) already doesn't await this function, so the work proceeds in the background. Tests still await the function and observe all work completing. Net: ~up-to-5s faster ready-signal-to-wire latency for users with auto-discovery; no behaviour change for the work itself or its ordering within the function. Regression test asserts readiness fires before both the command-queue add and the discovery trigger.
1 parent 788a5d2 commit 793dfe5

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

src/bridgeInitializationService.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ class BridgeInitializationService {
2323
this.bridge._lastInitTime = now;
2424
this.bridge.log('ALL CONNECTED - Initializing services...');
2525

26+
// Signal readiness up-front. All connection-health checks have already
27+
// passed by the time this handler fires, and the post-connect work
28+
// below (auto-discover, initial getall, HA Discovery TreeXML sweep) is
29+
// initialization that doesn't gate the bridge's ability to serve. The
30+
// production caller does not await this function, so moving the signal
31+
// up lets the readiness MQTT publish land on the wire before the
32+
// (potentially 5s) auto-discovery wait. Tests that await the function
33+
// still observe all work completing as before.
34+
this.bridge._updateBridgeReadiness('all-connected');
35+
2636
// Auto-discover networks from C-Gate if enabled and no explicit config overrides it
2737
if (this.bridge.settings.autoDiscoverNetworks) {
2838
await this._discoverNetworks();
@@ -65,7 +75,6 @@ class BridgeInitializationService {
6575
this.bridge.haDiscovery.trigger(this.bridge.discoveredNetworks || null);
6676
}
6777

68-
this.bridge._updateBridgeReadiness('all-connected');
6978
this._logStartupSummary();
7079
}
7180

tests/bridgeInitializationService.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,35 @@ describe('BridgeInitializationService', () => {
427427
expect(bridge._updateBridgeReadiness).toHaveBeenCalledWith('all-connected');
428428
});
429429

430+
it('signals readiness BEFORE running the post-connect init work', async () => {
431+
// The whole point of the v1.9.1 deferral: readiness MUST publish
432+
// before any of the post-connect work (auto-discovery wait,
433+
// initial getall queue, HA Discovery trigger). Capture the call
434+
// order across the readiness signal, the command-queue add, and
435+
// the haDiscovery construction.
436+
const { bridge, commandQueueAdd } = makeBridge({
437+
ha_discovery_enabled: true,
438+
getallonstart: true,
439+
getall_networks: [254]
440+
});
441+
442+
const eventOrder = [];
443+
bridge._updateBridgeReadiness = jest.fn(() => eventOrder.push('readiness'));
444+
commandQueueAdd.mockImplementation(() => eventOrder.push('queue-add'));
445+
HaDiscovery.mockImplementation(() => {
446+
eventOrder.push('discovery-ctor');
447+
return { trigger: jest.fn(() => eventOrder.push('discovery-trigger')) };
448+
});
449+
450+
const svc = new BridgeInitializationService(bridge);
451+
await svc.handleAllConnected();
452+
453+
// readiness fires first - then the rest of the post-connect work.
454+
expect(eventOrder[0]).toBe('readiness');
455+
expect(eventOrder).toContain('queue-add');
456+
expect(eventOrder).toContain('discovery-trigger');
457+
});
458+
430459
it('passes working publish callback to HaDiscovery', async () => {
431460
const { bridge, mqttPublish } = makeBridge({ ha_discovery_enabled: true });
432461
const svc = new BridgeInitializationService(bridge);

0 commit comments

Comments
 (0)