embedded_redis_client 0.1.0

Automatically runs a local redis-server instance
Documentation
use std::time::Duration;

use crate::embedded_redis_server::connection::{
    get_redis_server_connection, try_to_get_redis_server_connection_until_timeout,
};
use crate::embedded_redis_server::states::{ReadyToStart, RedisServerRunningInAnotherProcess};
use crate::embedded_redis_server::util::get_processes_using_target_port;
use crate::embedded_redis_server::{EmbeddedRedisServer, RedisServerConnectionSettings};
use crate::error::{EmbeddedRedisClientError, ErrorType};

pub struct CheckingRedisServerEnvironment {
    pub redis_server_connection: Option<redis::Connection>,
}

// Check if Redis is running in another process
// Check if the port if free

impl CheckingRedisServerEnvironment {
    pub fn start(
        connection_settings: RedisServerConnectionSettings,
        max_duration_to_attempt_connection: Duration,
    ) -> Result<EmbeddedRedisServer, EmbeddedRedisClientError> {
        match get_redis_server_connection(connection_settings.clone()) {
            Ok(connection) => {
                let environment = CheckingRedisServerEnvironment {
                    redis_server_connection: Some(connection),
                };
                let state = RedisServerRunningInAnotherProcess::try_from(environment)?;
                Ok(EmbeddedRedisServer::RunningInAnotherProcess(state))
            }
            Err(_) => {
                let environment = CheckingRedisServerEnvironment {
                    redis_server_connection: None,
                };
                let process_using_target_port =
                    get_processes_using_target_port(connection_settings.server_address.port());
                if process_using_target_port.is_empty() {
                    Ok(EmbeddedRedisServer::ReadyToStart(ReadyToStart::from(
                        environment,
                    )))
                } else {
                    // It might be that another process is in the process of starting a redis server, and has already blocked the port but is not yet ready to accept a new connection
                    match try_to_get_redis_server_connection_until_timeout(
                        connection_settings.clone(),
                        max_duration_to_attempt_connection,
                    ) {
                        Ok(_) => CheckingRedisServerEnvironment::start(
                            connection_settings,
                            max_duration_to_attempt_connection,
                        ),
                        Err(_) => {
                            let error_context = format!("These processses are using redis' port {} without enabling a connection: {:#?}\n", connection_settings.server_address, process_using_target_port);
                            if cfg!(debug_assertions) {
                                println!("{}", error_context);
                            }
                            Err(EmbeddedRedisClientError::new(
                                ErrorType::ServerEnvironment,
                                error_context,
                            ))
                        }
                    }
                }
            }
        }
    }

    // pub fn get_connection(&self) -> Option<redis::Connection> {
    //     self.redis_server_connection
    // }
}