eureka-client 0.0.4

Handles HTTP requests to and registering a service with Eureka
Documentation
pub use rest::structures::{Instance, PortData, StatusType};
use rest::EurekaRestClient;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use EurekaError;

#[derive(Debug)]
pub struct InstanceClient {
    client: Arc<EurekaRestClient>,
    config: Arc<Instance>,
    is_running: Arc<AtomicBool>,
}

impl InstanceClient {
    pub fn new(base_url: String, config: Instance) -> Self {
        InstanceClient {
            client: Arc::new(EurekaRestClient::new(base_url)),
            config: Arc::new(config),
            is_running: Arc::new(AtomicBool::new(false)),
        }
    }

    pub fn start(&self) {
        while let Err(e) = self.client.register(&self.config.app, &*self.config) {
            error!("Failed to register app: {}", e);
            thread::sleep(Duration::from_secs(15));
        }
        debug!("Registered app with eureka");

        self.is_running.store(true, Ordering::Relaxed);

        let is_running = Arc::clone(&self.is_running);
        let client = Arc::clone(&self.client);
        let config = Arc::clone(&self.config);
        thread::spawn(move || {
            thread::sleep(Duration::from_secs(30));
            while is_running.load(Ordering::Relaxed) {
                let resp = client.send_heartbeat(&config.app, &config.host_name);
                match resp {
                    Err(EurekaError::UnexpectedState(_)) => {
                        warn!("App not registered with eureka, reregistering");
                        let _ = client.register(&config.app, &*config);
                    }
                    Err(e) => {
                        error!("Failed to send heartbeat: {}", e);
                    }
                    Ok(_) => {
                        debug!("Sent heartbeat successfully");
                    }
                }
                thread::sleep(Duration::from_secs(30));
            }
        });

        while let Err(e) =
            self.client
                .update_status(&self.config.app, &self.config.host_name, StatusType::Up)
        {
            error!("Failed to set app to UP: {}", e);
            thread::sleep(Duration::from_secs(15));
        }
    }
}

impl Drop for InstanceClient {
    fn drop(&mut self) {
        self.is_running.store(false, Ordering::Relaxed);
        let _ = self
            .client
            .deregister(&self.config.app, &self.config.host_name);
    }
}