diff --git a/src/lib.rs b/src/lib.rs index 1d24d1d..275e3b8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -621,6 +621,8 @@ impl Deref for System { impl SystemHandle { /// Stops all actors spawned by this system. pub fn shutdown(&self) -> Result<(), ActorError> { + let shutdown_start = Instant::now(); + let current_thread = thread::current(); let current_thread_name = current_thread.name().unwrap_or("Unknown thread id"); info!("Thread [{}] shutting down the actor system", current_thread_name); @@ -656,18 +658,26 @@ impl SystemHandle { let err_count = { let mut registry = self.registry.lock(); debug!("[{}] joining {} actor threads.", self.name, registry.len()); - // Joining actors in the reverse order in which they are spawn. + + // Stopping actors in the reverse order in which they were spawned. + // We send the Stop control message to all actors first so they can + // all shut down in parallel, so actors will be in the process of + // stopping when we join the threads below. + for entry in registry.iter_mut().rev() { + let actor_name = entry.name(); + + if let Err(e) = entry.control_addr().send(Control::Stop) { + warn!("control channel is closed: {} ({})", actor_name, e); + } + } + registry .drain(..) .rev() .enumerate() - .filter_map(|(i, mut entry)| { + .filter_map(|(i, entry)| { let actor_name = entry.name(); - if let Err(e) = entry.control_addr().send(Control::Stop) { - warn!("control channel is closed: {} ({})", actor_name, e); - } - match entry { RegistryEntry::CurrentThread(_) => None, RegistryEntry::BackgroundThread(_control_addr, thread_handle) => { @@ -689,7 +699,7 @@ impl SystemHandle { .count() }; - info!("[{}] system finished shutting down.", self.name); + info!("[{}] system finished shutting down in {:?}", self.name, shutdown_start.elapsed()); if let Some(callback) = self.callbacks.postshutdown.as_ref() { info!("[{}] calling post-shutdown callback.", self.name);