{"type":"remove","actor"} shuts the actor down normally, drops its
mailbox, supervisor and actor.json entry (so also its subscriptions and
tap), and deletes /actor/<id>/. Native actors cannot be removed.
Re-applied from card-1-broker-remove (3c91747) onto card-2-broker-tap.
This commit is contained in:
+33
-3
@@ -1,7 +1,7 @@
|
||||
//! The broker: message routing, mailboxes, subscriptions, taps, the version
|
||||
//! store, and the requests to `broker` (spawn, upgrade, rollback, stop, start,
|
||||
//! subscribe, unsubscribe, tap, untap, scan, exit). `supervisor.rs` runs each
|
||||
//! WASM actor.
|
||||
//! remove, subscribe, unsubscribe, tap, untap, scan, exit). `supervisor.rs`
|
||||
//! runs each WASM actor.
|
||||
//!
|
||||
//! The broker accepts only `.wasm` files. It does not know any source language.
|
||||
//! The world folder is the source of truth: `scan` boots every
|
||||
@@ -377,6 +377,35 @@ impl Broker {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Stop an actor (normal shutdown) and delete its folder `actor/<id>/`.
|
||||
/// Afterwards the ID is unknown: messages to it are undeliverable, and
|
||||
/// it can be spawned again from scratch.
|
||||
pub async fn remove_actor(&self, id: &str) -> Result<Value> {
|
||||
if NATIVE.contains(&id) {
|
||||
bail!("{id} is part of the host and cannot be removed");
|
||||
}
|
||||
if !world::valid_id(id) {
|
||||
bail!("invalid actor ID {id:?}");
|
||||
}
|
||||
let lock = self.op_lock(id);
|
||||
let _guard = lock.lock().await;
|
||||
let dir = self.world.actor_dir(id);
|
||||
if !self.is_supervised(id) && !dir.is_dir() {
|
||||
bail!("no actor with ID {id}");
|
||||
}
|
||||
if self.is_supervised(id) {
|
||||
self.control(id, |reply| Control::Shutdown { reply }).await?;
|
||||
}
|
||||
// Without its mailbox, messages to `id` are undeliverable.
|
||||
self.controls.lock().unwrap().remove(id);
|
||||
self.mailboxes.lock().unwrap().remove(id);
|
||||
self.metas.lock().unwrap().remove(id);
|
||||
if dir.exists() {
|
||||
std::fs::remove_dir_all(&dir).with_context(|| format!("delete {}", dir.display()))?;
|
||||
}
|
||||
Ok(json!({"type": "removed", "actor": id}))
|
||||
}
|
||||
|
||||
/// Boot the actors in `actor/`. Called at start and on `scan`.
|
||||
///
|
||||
/// - An `actor.wasm` equal to the installed version starts as is.
|
||||
@@ -481,6 +510,7 @@ impl Broker {
|
||||
}
|
||||
"stop" => self.control(&actor()?, |reply| Control::Stop { reply }).await,
|
||||
"start" => self.control(&actor()?, |reply| Control::Start { reply }).await,
|
||||
"remove" => self.remove_actor(&actor()?).await,
|
||||
"subscribe" | "unsubscribe" => {
|
||||
let publisher = actor()?;
|
||||
let on = ty == "subscribe";
|
||||
@@ -506,7 +536,7 @@ impl Broker {
|
||||
self.exit.notify_one();
|
||||
Ok(json!({"type": "exiting"}))
|
||||
}
|
||||
other => bail!("unknown broker request {other:?}. Known: spawn, upgrade, rollback, stop, start, subscribe, unsubscribe, tap, untap, scan, exit"),
|
||||
other => bail!("unknown broker request {other:?}. Known: spawn, upgrade, rollback, stop, start, remove, subscribe, unsubscribe, tap, untap, scan, exit"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user