Skip to content

Commit 377ae64

Browse files
authored
add db cli command for marking a drones backends as lost (#848)
1 parent f85c123 commit 377ae64

5 files changed

+163
-12
lines changed

plane/.sqlx/query-5b6d66015eb731e4e65c9d28795c707b6d93b58a6b814fc1babb40e61fa8d748.json

+77
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plane/src/bin/db-cli.rs

+33-3
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,18 @@ enum Command {
4949
cleanup_batch_size: Option<i32>,
5050
},
5151
MarkBackendLost {
52-
#[arg(required = true)]
52+
#[arg(required = false)]
5353
backends: Vec<BackendName>,
54+
55+
/// If provided, all alive backends on the drone will be marked as lost.
56+
/// Must also provide a cluster.
57+
#[clap(long)]
58+
drone: Option<DroneName>,
59+
60+
/// If provided, all alive backends on the drone will be marked as lost.
61+
/// Must also provide a drone.
62+
#[clap(long)]
63+
cluster: Option<ClusterName>,
5464
},
5565
}
5666

@@ -138,10 +148,30 @@ async fn main_inner(opts: Opts) -> anyhow::Result<()> {
138148
);
139149
}
140150
}
141-
Command::MarkBackendLost { backends } => {
151+
Command::MarkBackendLost {
152+
backends,
153+
drone,
154+
cluster,
155+
} => {
142156
let stdin = std::io::stdin();
143157

144-
for backend in backends {
158+
let backends_to_mark = match (drone, cluster, backends.is_empty()) {
159+
(Some(drone), Some(cluster), true) => db
160+
.backend()
161+
.list_alive_backends_for_drone(&cluster, &drone)
162+
.await?
163+
.into_iter()
164+
.map(|b| b.id)
165+
.collect(),
166+
(None, None, false) => backends,
167+
_ => {
168+
return Err(anyhow::anyhow!(
169+
"Must either provide a list of backends, or a drone and cluster"
170+
));
171+
}
172+
};
173+
174+
for backend in backends_to_mark {
145175
let Some(backend) = db.backend().backend(&backend).await? else {
146176
println!("Could not find backend: {}, skipping...", backend);
147177
continue;

plane/src/database/backend.rs

+51-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::{
44
};
55
use crate::{
66
log_types::BackendAddr,
7-
names::{BackendActionName, BackendName},
7+
names::{BackendActionName, BackendName, DroneName},
88
protocol::{BackendAction, RouteInfo},
99
types::{
1010
backend_state::BackendStatusStreamEntry, BackendState, BackendStatus, BearerToken,
@@ -290,6 +290,56 @@ impl<'a> BackendDatabase<'a> {
290290
Ok(result)
291291
}
292292

293+
pub async fn list_alive_backends_for_drone(
294+
&self,
295+
cluster: &ClusterName,
296+
drone: &DroneName,
297+
) -> sqlx::Result<Vec<BackendRow>> {
298+
let query_result = sqlx::query!(
299+
r#"
300+
select
301+
id,
302+
cluster,
303+
last_status,
304+
last_status_time,
305+
state,
306+
drone_id,
307+
expiration_time,
308+
allowed_idle_seconds,
309+
last_keepalive,
310+
now() as "as_of!"
311+
from backend
312+
where
313+
drone_id = (select id from node where name = $1 and cluster = $2) and
314+
last_status != 'terminated'
315+
"#,
316+
drone.to_string(),
317+
cluster.to_string(),
318+
)
319+
.fetch_all(&self.db.pool)
320+
.await?;
321+
322+
let mut result = Vec::new();
323+
324+
for row in query_result {
325+
result.push(BackendRow {
326+
id: BackendName::try_from(row.id)
327+
.map_err(|_| sqlx::Error::Decode("Failed to decode backend name.".into()))?,
328+
cluster: row.cluster,
329+
last_status_time: row.last_status_time,
330+
state: serde_json::from_value(row.state)
331+
.map_err(|_| sqlx::Error::Decode("Failed to decode backend state.".into()))?,
332+
last_keepalive: row.last_keepalive,
333+
drone_id: NodeId::from(row.drone_id),
334+
expiration_time: row.expiration_time,
335+
allowed_idle_seconds: row.allowed_idle_seconds,
336+
as_of: row.as_of,
337+
});
338+
}
339+
340+
Ok(result)
341+
}
342+
293343
pub async fn route_info_for_static_token(
294344
&self,
295345
token: &BearerToken,

plane/src/drone/backend_manager.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,7 @@ impl BackendManager {
259259
}
260260
}
261261

262-
pub async fn terminate(
263-
self: &Arc<Self>,
264-
kind: TerminationKind,
265-
reason: TerminationReason,
266-
) -> Result<()> {
262+
pub async fn terminate(self: &Arc<Self>, kind: TerminationKind, reason: TerminationReason) {
267263
let state = self
268264
.state
269265
.lock()
@@ -276,8 +272,6 @@ impl BackendManager {
276272
TerminationKind::Hard => state.to_hard_terminating(reason),
277273
};
278274
self.set_state(new_state);
279-
280-
Ok(())
281275
}
282276

283277
pub fn mark_terminated(self: &Arc<Self>, exit_code: Option<i32>) -> Result<()> {

plane/src/drone/executor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ impl Executor {
232232
manager.clone()
233233
};
234234

235-
manager.terminate(*kind, *reason).await?;
235+
manager.terminate(*kind, *reason).await;
236236
}
237237
}
238238

0 commit comments

Comments
 (0)