(state: &State<'_, AppState>)
| 2179 | } |
| 2180 | |
| 2181 | async fn prune_unrecoverable_remote_workspaces(state: &State<'_, AppState>) -> usize { |
| 2182 | let saved_connection_ids: std::collections::HashSet<String> = |
| 2183 | match state.get_ssh_manager_async().await { |
| 2184 | Ok(manager) => manager |
| 2185 | .get_saved_connections() |
| 2186 | .await |
| 2187 | .into_iter() |
| 2188 | .map(|connection| connection.id) |
| 2189 | .collect(), |
| 2190 | Err(error) => { |
| 2191 | warn!( |
| 2192 | "Skipping remote workspace cleanup because SSH manager is unavailable: {}", |
| 2193 | error |
| 2194 | ); |
| 2195 | return 0; |
| 2196 | } |
| 2197 | }; |
| 2198 | |
| 2199 | let workspaces = state.workspace_service.list_workspace_infos().await; |
| 2200 | let mut removed = 0usize; |
| 2201 | |
| 2202 | for workspace in workspaces { |
| 2203 | if workspace.workspace_kind != WorkspaceKind::Remote { |
| 2204 | continue; |
| 2205 | } |
| 2206 | |
| 2207 | let connection_id = workspace |
| 2208 | .metadata |
| 2209 | .get("connectionId") |
| 2210 | .and_then(|value| value.as_str()) |
| 2211 | .map(str::trim) |
| 2212 | .filter(|value| !value.is_empty()) |
| 2213 | .map(str::to_string); |
| 2214 | |
| 2215 | let should_remove = connection_id |
| 2216 | .as_deref() |
| 2217 | .map(|id| !saved_connection_ids.contains(id)) |
| 2218 | .unwrap_or(true); |
| 2219 | |
| 2220 | if !should_remove { |
| 2221 | continue; |
| 2222 | } |
| 2223 | |
| 2224 | if let Some(id) = connection_id.as_deref() { |
| 2225 | state |
| 2226 | .unregister_remote_workspace_entry(id, &workspace.root_path.to_string_lossy()) |
| 2227 | .await; |
| 2228 | } |
| 2229 | |
| 2230 | match state |
| 2231 | .workspace_service |
| 2232 | .remove_workspace(&workspace.id) |
| 2233 | .await |
| 2234 | { |
| 2235 | Ok(()) => { |
| 2236 | removed += 1; |
| 2237 | info!( |
| 2238 | "Removed unrecoverable remote workspace: workspace_id={}, connection_id={:?}, path={}", |
no test coverage detected