{"type":"remove","actor"} shuts the actor down normally, drops its
mailbox and supervisor, and deletes /actor/<id>/. Native actors cannot
be removed. Test in cli/tests/host.rs, documented in PROTOCOL.md.
This commit is contained in:
+32
-2
@@ -1,6 +1,6 @@
|
||||
//! The broker: message routing, mailboxes, subscriptions, the version store,
|
||||
//! and the requests to `broker` (spawn, upgrade, rollback, stop, start,
|
||||
//! subscribe, unsubscribe, scan, exit). `supervisor.rs` runs each WASM actor.
|
||||
//! remove, subscribe, unsubscribe, 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
|
||||
@@ -351,6 +351,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.
|
||||
@@ -455,6 +484,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";
|
||||
@@ -474,7 +504,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, scan, exit"),
|
||||
other => bail!("unknown broker request {other:?}. Known: spawn, upgrade, rollback, stop, start, remove, subscribe, unsubscribe, scan, exit"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user