## derive_hub A simple actor hub that generates the following code. ``` #[derive(::derive_builder::Builder, ::std::fmt::Debug)] pub struct #hub_name { #[builder(setter(skip))] workers: ::std::vec::Vec, #(#field_declarations,)* } impl ::std::ops::Drop for #hub_name { fn drop(&mut self) { self.shutdown(); } } impl #hub_name { /// Spawns a given number of workers threads. /// #[inline] pub fn spawn(&mut self, worker_count: usize) -> ::std::vec::Vec<::tokio::task::JoinHandle<()>> { assert!(worker_count > 0, "Worker count has to be greater than zero, but got {}", worker_count); (0..worker_count) .map(|_| { let token = ::tokio_util::sync::CancellationToken::new(); self.workers.push(token.clone()); let item = #item_builder::default() #(#inits)* .build() .expect(concat!("Should be able to build ", stringify!(#hub_name), ".")); ::tokio::spawn(async move { item.run(token).await; }) }) .collect::>() } /// Shutdown hub. /// #[inline] pub fn shutdown(&self) { for worker in &self.workers { worker.cancel(); } } } ``` ## Inert Attributes: * #[hub(skip)] - Should be used in conjunction with default functions of the builder of the agent struct. ## Preconditions: * Crates that have to be installed: Tikio, tokio-util, derive-builder. * The members of the struct should be inside an Arc, which will be cloned by the hub when spawning. * Naturally, all members have to be syn and send. * The struct has to implemnet derive_builder::Builder * The struct that has the derive attribute has to have a method of same signature as this example: ``` pub async fn run(self, flag: tokio_util::sync::CancellationToken) { loop { tokio::select! { biased; _ = flag.cancelled() => { /* Wind down actor */ break; } item = self.foo.pop() => { /* Do something important */ } item = self.bar.pop() => { /* Do something important */ } item = self.baz.pop() => { /* Do something important */ } }; } } ``` ## Recommendations. * Fields should ideally contain a deadqueue::Queue.