pub async fn run(config: Config, rt: Handle) -> io::Result<()> {
    assert!(config.config_type.is_manager());

    if let Some(nofile) = config.nofile {
        debug!("Setting RLIMIT_NOFILE to {}", nofile);
        if let Err(err) = set_nofile(nofile) {
            match err.kind() {
                ErrorKind::PermissionDenied => {
                    warn!("Insufficient permission to change RLIMIT_NOFILE, try to restart as root user");
                }
                ErrorKind::InvalidInput => {
                    warn!("Invalid `nofile` value {}, decrease it and try again", nofile);
                }
                _ => {
                    error!("Failed to set RLIMIT_NOFILE with value {}, error: {}", nofile, err);
                }
            }
            return Err(err);
        }
    }

    // Create a context containing a DNS resolver and server running state flag.
    let state = ServerState::new_shared(&config, rt.clone()).await;
    let context = Context::new_shared(config, state.clone());

    let bind_addr = match context.config().manager_address {
        Some(ref a) => a,
        None => {
            let err = Error::new(ErrorKind::Other, "missing `manager_address` in configuration");
            return Err(err);
        }
    };

    let mut service = ManagerService::bind(bind_addr, context.clone()).await?;

    // Creates known servers in configuration
    let config = context.config();

    if !config.server.is_empty() {
        for svr_cfg in &config.server {
            let mut clean_config = Config::new(ConfigType::Server);
            clean_config.local = config.local.clone();
            clean_config.mode = config.mode;
            clean_config.no_delay = config.no_delay;
            clean_config.udp_timeout = config.udp_timeout;

            clean_config.server.push(svr_cfg.clone());

            service
                .start_server_with_config(svr_cfg.addr().port(), clean_config)
                .await?;
        }
    }

    service.serve().await
}
/// Server manager for supporting [Manage Multiple Users](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users) APIs
Server manager for supporting [Manage Multiple Users] APIs
Server manager for supporting [ Manage Multiple Users ] APIs
pub async fn run(config: Config, rt: Handle) -> io::Result<()> {
    assert!(config.config_type.is_manager());
    if let Some(nofile) = config.nofile {
        debug!("Setting RLIMIT_NOFILE to {}", nofile);
        if let Err(err) = set_nofile(nofile) {
            match err.kind() {
                ErrorKind::PermissionDenied => {
                    warn!("Insufficient permission to change RLIMIT_NOFILE, try to restart as root user");
                }
                ErrorKind::InvalidInput => {
                    warn!("Invalid `nofile` value {}, decrease it and try again", nofile);
                }
                _ => {
                    error!("Failed to set RLIMIT_NOFILE with value {}, error: {}", nofile, err);
                }
            }
            return Err(err);
        }
    }
    // Create a context containing a DNS resolver and server running state flag.
    let state = ServerState::new_shared(&config, rt.clone()).await;
    let context = Context::new_shared(config, state.clone());
    let bind_addr = match context.config().manager_address {
        Some(ref a) => a,
        None => {
            let err = Error::new(ErrorKind::Other, "missing `manager_address` in configuration");
            return Err(err);
        }
    };
    let mut service = ManagerService::bind(bind_addr, context.clone()).await?;
    // Creates known servers in configuration
    let config = context.config();
    if !config.server.is_empty() {
        for svr_cfg in &config.server {
            let mut clean_config = Config::new(ConfigType::Server);
            clean_config.local = config.local.clone();
            clean_config.mode = config.mode;
            clean_config.no_delay = config.no_delay;
            clean_config.udp_timeout = config.udp_timeout;
            clean_config.server.push(svr_cfg.clone());
            service
                .start_server_with_config(svr_cfg.addr().port(), clean_config)
                .await?;
        }
    }
    service.serve().await
}
pub async fn run ( config : Config , rt : Handle ) -> io :: Result < ( ) > { assert ! ( config config_type is_manager ( ) ) ; if let Some ( nofile ) = config . nofile { debug ! ( " " nofile ) ; if let Err ( err ) = set_nofile ( nofile ) { match err . kind ( ) { ErrorKind :: PermissionDenied => { warn ! ( " " ) ; } ErrorKind :: InvalidInput => { warn ! ( " " nofile ) ; } _ => { error ! ( " " nofile err ) ; } } return Err ( err ) ; } } // Create a context containing a DNS resolver and server running state flag. let state = ServerState :: new_shared ( & config , rt . clone ( ) ) . await ; let context = Context :: new_shared ( config , state . clone ( ) ) ; let bind_addr = match context . config ( ) . manager_address { Some ( ref a ) => a , None => { let err = Error :: new ( ErrorKind :: Other , " " ) ; return Err ( err ) ; } } ; let mut service = ManagerService :: bind ( bind_addr , context . clone ( ) ) . await ? ; // Creates known servers in configuration let config = context . config ( ) ; if ! config . server . is_empty ( ) { for svr_cfg in & config . server { let mut clean_config = Config :: new ( ConfigType :: Server ) ; clean_config . local = config . local . clone ( ) ; clean_config . mode = config . mode ; clean_config . no_delay = config . no_delay ; clean_config . udp_timeout = config . udp_timeout ; clean_config . server . push ( svr_cfg . clone ( ) ) ; service . start_server_with_config ( svr_cfg . addr ( ) . port ( ) , clean_config ) . await ? ; } } service . serve ( ) . await }
Server manager for supporting [Manage Multiple Users](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users) APIs
Server manager for supporting [ Manage Multiple Users ] ( https : // github . com / shadowsocks / shadowsocks / wiki / Manage - Multiple - Users ) APIs
config
Config
rt
Handle
config
Config
rt
Handle