Skip to content

Commit 8d4ff8a

Browse files
committed
fix: remove event-based api_server_connected — stale events caused restart loop
The connection_status_changed event handler was setting api_server_connected to false based on stale "disconnected" events fired during Launching (before Gateway finished logging in and labels became "connected"). When do_connected checked the flag on first entry, it saw false and triggered an immediate false-positive restart, doubling the launch time. Match IBC's reactive model (GatewayDialogHandler): disconnect detection happens via error dialog handling + active label inspection during Connected state, NOT via async event state. The event is now logged for observability only and does not drive state changes.
1 parent 5920d68 commit 8d4ff8a

2 files changed

Lines changed: 6 additions & 22 deletions

File tree

ibctl/src/state_machine/mod.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,13 @@ impl StateMachine {
415415
);
416416
}
417417
AgentEvent::ConnectionStatusChanged { ref from, ref to, .. } => {
418+
// Informational only — do NOT drive state changes from this event.
419+
// Events can arrive with stale "disconnected" state while the state
420+
// machine is still in Launching/Login, and would trigger false-positive
421+
// restarts on first Connected entry. Match IBC's reactive model:
422+
// disconnect detection happens via error dialog handling + active
423+
// label inspection during Connected state.
418424
log::warn!("Event: connection_status_changed {} -> {}", from, to);
419-
self.api_server_connected = to == "connected";
420425
}
421426
}
422427

@@ -1283,23 +1288,6 @@ impl StateMachine {
12831288
self.start_socat(api_port, socat_port);
12841289
}
12851290

1286-
// --- API Server disconnect detection (real-time event from Java agent) ---
1287-
if !self.api_server_connected {
1288-
log::warn!("API Server DISCONNECTED (detected via connection_status_changed event)");
1289-
self.stop_socat();
1290-
self.abort_client_id_task();
1291-
self.connected_window_class = None;
1292-
self.handler_registry.reset();
1293-
// Click OK on any error dialogs before restarting
1294-
if let Ok(windows) = self.agent_client.list_windows().await {
1295-
for w in &windows {
1296-
let _ = self.agent_client.click_button(w.id, "OK").await;
1297-
}
1298-
}
1299-
self.api_server_connected = true; // Reset for next cycle
1300-
return Ok(State::Restarting);
1301-
}
1302-
13031291
// --- Event-driven dialog detection (observation cache) ---
13041292
// Check the observation cache for re-login dialogs and session loss.
13051293
// Events update the cache in real-time; this is instant (no I/O).

ibctl/src/state_machine/types.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,6 @@ pub struct StateMachine {
206206
/// session loss: if the main window's class changes (e.g. ibgateway.ay → ibgateway.az),
207207
/// Gateway reverted to the login form without showing a RE-LOGIN dialog.
208208
pub(super) connected_window_class: Option<String>,
209-
/// API Server connection status from Java agent's connection_status_changed event.
210-
/// Updated in real-time by the event stream. Checked by do_connected handler.
211-
pub(super) api_server_connected: bool,
212209
/// 2FA device selection state — survives tokio::select! cancellation.
213210
/// Set true after device is selected and OK clicked. Reset on state transitions
214211
/// that start a new login cycle.
@@ -276,7 +273,6 @@ impl StateMachine {
276273
client_id_rx: None,
277274
relogin_attempts: 0,
278275
connected_window_class: None,
279-
api_server_connected: true,
280276
twofa_device_selected: false,
281277
twofa_seen: false,
282278
twofa_gone_at: None,

0 commit comments

Comments
 (0)