Skip to content
Merged
Show file tree
Hide file tree
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
53 changes: 42 additions & 11 deletions crates/fbuild-daemon/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,27 +378,58 @@ impl DaemonContext {
.clone()
}

pub fn refresh_devices_and_broadcast_serial_moves(&self) {
pub async fn refresh_devices_and_broadcast_serial_moves(&self) {
self.device_manager.refresh_devices();
self.broadcast_recent_device_port_moves();
self.rebind_recent_device_port_moves().await;
}

pub fn refresh_devices_if_stale_and_broadcast_serial_moves(&self, max_age: Duration) -> bool {
pub async fn refresh_devices_if_stale_and_broadcast_serial_moves(
&self,
max_age: Duration,
) -> bool {
let refreshed = self.device_manager.refresh_devices_if_stale(max_age);
if refreshed {
self.broadcast_recent_device_port_moves();
self.rebind_recent_device_port_moves().await;
}
refreshed
}

fn broadcast_recent_device_port_moves(&self) {
async fn rebind_recent_device_port_moves(&self) {
for move_event in self.device_manager.take_recent_port_moves() {
self.serial_manager.notify_port_renumbered(
&move_event.previous_port,
&move_event.port,
"tracked_serial_move",
move_event.serial_number,
);
match self
.serial_manager
.rebind_port_session(
&move_event.previous_port,
&move_event.port,
"tracked_serial_move",
move_event.serial_number.clone(),
)
.await
{
Ok(true) => {}
Ok(false) => {
self.serial_manager.notify_port_renumbered(
&move_event.previous_port,
&move_event.port,
"tracked_serial_move",
move_event.serial_number,
);
}
Err(err) => {
self.serial_manager.notify_port_rebind_failed(
&move_event.previous_port,
&move_event.port,
"open_failed",
err.to_string(),
);
tracing::warn!(
previous_port = move_event.previous_port,
port = move_event.port,
"failed to rebind serial session after tracked port move: {}",
err
);
}
}
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/fbuild-daemon/src/handlers/devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use uuid::Uuid;
/// POST /api/devices/list
pub async fn list_devices(state: State<Arc<DaemonContext>>) -> Json<DeviceListResponse> {
// Refresh device inventory
state.refresh_devices_and_broadcast_serial_moves();
state.refresh_devices_and_broadcast_serial_moves().await;

let all = state.device_manager.get_all_devices();
let devices = all.values().map(device_info).collect();
Expand All @@ -32,7 +32,7 @@ pub async fn device_status(
Path(port): Path<String>,
) -> Json<DeviceStatusResponse> {
// Refresh to get latest state
state.refresh_devices_and_broadcast_serial_moves();
state.refresh_devices_and_broadcast_serial_moves().await;

match state.device_manager.get_device_status(&port) {
Some(ds) => Json(device_status_response(ds)),
Expand Down Expand Up @@ -99,7 +99,7 @@ pub async fn device_lease(
let client_id = req.client_id.unwrap_or_else(|| Uuid::new_v4().to_string());

// Ensure devices are refreshed
state.refresh_devices_and_broadcast_serial_moves();
state.refresh_devices_and_broadcast_serial_moves().await;

let result = match req.lease_type.as_str() {
"exclusive" => state.device_manager.acquire_exclusive(
Expand Down Expand Up @@ -178,7 +178,7 @@ pub async fn device_preempt(
let client_id = req.client_id.unwrap_or_else(|| Uuid::new_v4().to_string());

// Refresh first
state.refresh_devices_and_broadcast_serial_moves();
state.refresh_devices_and_broadcast_serial_moves().await;

match state
.device_manager
Expand Down
5 changes: 3 additions & 2 deletions crates/fbuild-daemon/src/handlers/operations/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ pub async fn deploy(
}

let deploy_port_choice = if req.port.is_none() {
ctx.refresh_devices_and_broadcast_serial_moves();
ctx.refresh_devices_and_broadcast_serial_moves().await;
choose_deploy_port(
None,
platform,
Expand Down Expand Up @@ -412,7 +412,8 @@ pub async fn deploy(
// the trust-check still requires `is_connected == true` on the
// cached DeviceState, which the most-recent refresh supplied.
if trusted_hash_enabled {
ctx.refresh_devices_if_stale_and_broadcast_serial_moves(std::time::Duration::from_secs(2));
ctx.refresh_devices_if_stale_and_broadcast_serial_moves(std::time::Duration::from_secs(2))
.await;
}
let deploy_result = tokio::task::spawn_blocking(move || -> fbuild_core::Result<(Option<Box<dyn fbuild_deploy::Deployer>>, fbuild_deploy::DeploymentResult)> {
// Populated by the Espressif32 arm with (image_hash, port).
Expand Down
10 changes: 10 additions & 0 deletions crates/fbuild-daemon/src/handlers/operations/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,16 @@ pub(crate) async fn run_monitor_loop(
}
Ok(Ok(SerialStreamEvent::PortRenumbered { .. }))
| Ok(Ok(SerialStreamEvent::PortReattached { .. })) => {}
Ok(Ok(SerialStreamEvent::PortRebindFailed {
port,
new_port,
reason,
message,
})) => {
return MonitorOutcome::Error(format!(
"serial port {port} failed to rebind to {new_port} ({reason}): {message}"
));
}
Ok(Err(tokio::sync::broadcast::error::RecvError::Lagged(n))) => {
tracing::warn!("monitor lagged, skipped {} messages", n);
}
Expand Down
11 changes: 11 additions & 0 deletions crates/fbuild-daemon/src/handlers/websockets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,17 @@ async fn handle_serial_ws(mut socket: WebSocket, ctx: Arc<DaemonContext>) {
break;
}
}
Ok(SerialStreamEvent::PortRebindFailed { port, new_port, reason, message }) => {
let msg = SerialServerMessage::PortRebindFailed {
port,
new_port,
reason,
message,
};
if socket.send(Message::Text(serde_json::to_string(&msg).unwrap())).await.is_err() {
break;
}
}
Err(tokio::sync::broadcast::error::RecvError::Lagged(n)) => {
tracing::warn!(client_id, port, n, "reader lagged, skipping lines");
}
Expand Down
1 change: 1 addition & 0 deletions crates/fbuild-python/src/json_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub(crate) async fn read_lines_async(
Ok(ServerMessage::Reconnected { .. }) => continue,
Ok(ServerMessage::PortRenumbered { .. })
| Ok(ServerMessage::PortReattached { .. }) => continue,
Ok(ServerMessage::PortRebindFailed { .. }) => break,
Ok(ServerMessage::PortDisconnected { .. }) => break,
_ => continue,
}
Expand Down
10 changes: 10 additions & 0 deletions crates/fbuild-python/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ pub(crate) enum ServerMessage {
#[allow(dead_code)]
previous_port: String,
},
PortRebindFailed {
#[allow(dead_code)]
port: String,
#[allow(dead_code)]
new_port: String,
#[allow(dead_code)]
reason: String,
#[allow(dead_code)]
message: String,
},
Error {
message: String,
},
Expand Down
2 changes: 2 additions & 0 deletions crates/fbuild-python/src/serial_monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl SerialMonitor {
}
Ok(ServerMessage::PortRenumbered { .. })
| Ok(ServerMessage::PortReattached { .. }) => continue,
Ok(ServerMessage::PortRebindFailed { .. }) => break,
Ok(ServerMessage::PortDisconnected { .. }) => break,
_ => continue,
}
Expand Down Expand Up @@ -559,6 +560,7 @@ impl SerialMonitor {
}
Ok(ServerMessage::PortRenumbered { .. })
| Ok(ServerMessage::PortReattached { .. }) => continue,
Ok(ServerMessage::PortRebindFailed { .. }) => break,
Ok(ServerMessage::PortDisconnected { .. }) => break,
_ => continue,
}
Expand Down
Loading
Loading