anthill-service-system

Rust runtime service system manager with di integration

Example

```rust

use std::sync::Arc; use std::time::Duration;

use anthilldi::Injector; use anthilldi::{Injection, builders::ContainerBuilder}; use tokio::sync::RwLock; use tokio::sync::mpsc::{Receiver, Sender}; use tokio::task::JoinHandle;

use anthillservicesystem::utils::SystemState; use anthillservicesystem::{Service, ServiceSystemCofiguration}; use anthillservicesystem::ServiceSystemManager; use anthillservicesystem::extensions::AddServiceExtension;

struct TextWrapper1 { pub text: String }

impl Injection for TextWrapper1 { fn buildinjection(: &mut anthilldi::Injector) -> Result { Ok(Self{text: "test1".tostring()}) } }

struct TextWrapper2 { pub text: String }

impl Injection for TextWrapper2 { fn buildinjection(: &mut anthilldi::Injector) -> Result { Ok(Self{text: "test2".tostring()}) } }

struct TestService1 { service_task: Option

impl Injection for TestService1 { fn buildinjection(: &mut anthilldi::Injector) -> Result { Ok(Self{ servicetask: None, }) } }

[asynctrait::asynctrait]

impl Service for TestService1 { async fn onstart(&mut self, injector: Arc>) { let sender: Arc>> = injector.write().await.getsingletone().unwrap(); let textwrapper1: TextWrapper1 = injector.write().await.getnewinstance().unwrap(); let textwrapper2: TextWrapper2 = injector.write().await.getnewinstance().unwrap();

    self.service_task = Some(tokio::spawn(async move {
        use tokio::time::sleep;
        sleep(Duration::from_millis(1)).await;
        sender.write().await.send(format!("{}_{}", text_wrapper_1.text, text_wrapper_2.text)).await.unwrap();
    }));
}

async fn on_end(&mut self, _: Arc<RwLock<Injector>>) {
    if let Some(service_task) = self.service_task.take() {
        service_task.await.unwrap();
    }
}

}

struct TestService2 { service_task: Option

impl Injection for TestService2 { fn buildinjection(: &mut anthilldi::Injector) -> Result { Ok(Self{ servicetask: None, }) } }

[asynctrait::asynctrait]

impl Service for TestService2 { async fn onstart(&mut self, injector: Arc>) { let receiver: Arc>> = injector.write().await.getsingletone().unwrap(); let systemstate: Arc> = injector.write().await.getsingletone().unwrap();

    self.service_task = Some(tokio::spawn(async move {
        assert_eq!(receiver.write().await.recv().await.unwrap(), "test1_test2");
        system_state.write().await.stop();
    }));
}

async fn on_end(&mut self, _: Arc<RwLock<Injector>>) {
    if let Some(service_task) = self.service_task.take() {
        service_task.await.unwrap();
    }
}

}

struct TestConfiguration { }

[asynctrait::asynctrait]

impl ServiceSystemCofiguration for TestConfiguration { async fn configure_injections(&mut self, injector: Arc>) -> Result<(), String> { use tokio::sync::mpsc; let (sender, receiver) = mpsc::channel::(1);

    injector.write().await.add_container(ContainerBuilder::bind_type::<TextWrapper1>().build());
    injector.write().await.add_container(ContainerBuilder::bind_type::<TextWrapper2>().build());
    injector.write().await.add_container(ContainerBuilder::bind_unconfigured_type().build_with_value(sender));
    injector.write().await.add_container(ContainerBuilder::bind_unconfigured_type().build_with_value(receiver));

    Ok(())
}

async fn configure_services(&mut self, injector: Arc<RwLock<anthill_di::Injector>>) -> Result<(), String> {
    injector.write().await.add_service::<TestService1>().await.map_err(|e| format!("{:?}", e))?;
    injector.write().await.add_service::<TestService2>().await.map_err(|e| format!("{:?}", e))?;
    Ok(())
}

}

fn main() { let rt = Runtime::new().unwrap();

rt.block_on(async {
    ServiceSystemManager::new(Box::new(TestConfiguration{})).await.unwrap().run().await.unwrap();
});

}

```

Refs: