pub fn start_http_thread(
    path: &str,
    api_notifier: Option<Arc<Waker>>,
    to_api: Sender<Option<ApiRequest>>,
    from_api: Receiver<ApiResponse>,
) -> Result<(thread::JoinHandle<Result<()>>, Arc<Waker>)> {
    // Try to remove existed unix domain socket
    std::fs::remove_file(path).unwrap_or_default();
    let socket_path = PathBuf::from(path);

    let mut pool = Poll::new()?;
    let waker = Arc::new(Waker::new(pool.registry(), EXIT_TOKEN)?);
    let waker2 = waker.clone();
    let mut server = HttpServer::new(socket_path).map_err(|e| {
        if let ServerError::IOError(e) = e {
            e
        } else {
            Error::new(ErrorKind::Other, format!("{:?}", e))
        }
    })?;
    pool.registry().register(
        &mut SourceFd(&server.epoll().as_raw_fd()),
        REQUEST_TOKEN,
        Interest::READABLE,
    )?;

    let thread = thread::Builder::new()
        .name("http-server".to_string())
        .spawn(move || {
            // Must start the server successfully or just die by panic
            server.start_server().unwrap();
            let mut events = Events::with_capacity(100);
            let mut do_exit = false;

            info!("http server started");

            loop {
                match pool.poll(&mut events, None) {
                    Err(e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
                    Err(e) => {
                        error!("http server poll events failed, {}", e);
                        exit_api_server(api_notifier, &to_api);
                        return Err(e);
                    }
                    Ok(_) => {}
                }

                for event in &events {
                    match event.token() {
                        EXIT_TOKEN => do_exit = true,
                        REQUEST_TOKEN => match server.requests() {
                            Ok(request_vec) => {
                                for server_request in request_vec {
                                    let reply = server_request.process(|request| {
                                        handle_http_request(
                                            request,
                                            api_notifier.clone(),
                                            &to_api,
                                            &from_api,
                                        )
                                    });
                                    // Ignore error when sending response
                                    server.respond(reply).unwrap_or_else(|e| {
                                        error!("HTTP server error on response: {}", e)
                                    });
                                }
                            }
                            Err(e) => {
                                error!("HTTP server error on retrieving incoming request: {}", e);
                            }
                        },
                        _ => unreachable!("unknown poll token."),
                    }
                }

                if do_exit {
                    exit_api_server(api_notifier, &to_api);
                    break;
                }
            }
            info!("http-server thread exits");
            // Keep the Waker alive to match the lifetime of the poll loop above
            drop(waker2);
            Ok(())
        })?;

    Ok((thread, waker))
}
/// Start a HTTP server parsing http requests and send to nydus API server a concrete
/// request to operate nydus or fetch working status.
/// The HTTP server sends request by `to_api` channel and wait for response from `from_api` channel
/// `api_notifier` is used to notify an execution context to fetch above request and handle it.
/// We can't forward signal to native rust thread, so we rely on `exit_evtfd` to notify
/// the server to exit. Therefore, it adds the unix domain socket fd receiving http request
/// to a global epoll_fd associated with a event_fd which will be used later to notify
/// the server thread to exit.
Start a HTTP server parsing http requests and send to nydus API server a concrete
request to operate nydus or fetch working status.
Start a HTTP server parsing http requests and send to nydus API server a concrete request to operate nydus or fetch working status .
pub fn start_http_thread(
    path: &str,
    api_notifier: Option<Arc<Waker>>,
    to_api: Sender<Option<ApiRequest>>,
    from_api: Receiver<ApiResponse>,
) -> Result<(thread::JoinHandle<Result<()>>, Arc<Waker>)> {
    // Try to remove existed unix domain socket
    std::fs::remove_file(path).unwrap_or_default();
    let socket_path = PathBuf::from(path);
    let mut pool = Poll::new()?;
    let waker = Arc::new(Waker::new(pool.registry(), EXIT_TOKEN)?);
    let waker2 = waker.clone();
    let mut server = HttpServer::new(socket_path).map_err(|e| {
        if let ServerError::IOError(e) = e {
            e
        } else {
            Error::new(ErrorKind::Other, format!("{:?}", e))
        }
    })?;
    pool.registry().register(
        &mut SourceFd(&server.epoll().as_raw_fd()),
        REQUEST_TOKEN,
        Interest::READABLE,
    )?;
    let thread = thread::Builder::new()
        .name("http-server".to_string())
        .spawn(move || {
            // Must start the server successfully or just die by panic
            server.start_server().unwrap();
            let mut events = Events::with_capacity(100);
            let mut do_exit = false;
            info!("http server started");
            loop {
                match pool.poll(&mut events, None) {
                    Err(e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
                    Err(e) => {
                        error!("http server poll events failed, {}", e);
                        exit_api_server(api_notifier, &to_api);
                        return Err(e);
                    }
                    Ok(_) => {}
                }
                for event in &events {
                    match event.token() {
                        EXIT_TOKEN => do_exit = true,
                        REQUEST_TOKEN => match server.requests() {
                            Ok(request_vec) => {
                                for server_request in request_vec {
                                    let reply = server_request.process(|request| {
                                        handle_http_request(
                                            request,
                                            api_notifier.clone(),
                                            &to_api,
                                            &from_api,
                                        )
                                    });
                                    // Ignore error when sending response
                                    server.respond(reply).unwrap_or_else(|e| {
                                        error!("HTTP server error on response: {}", e)
                                    });
                                }
                            }
                            Err(e) => {
                                error!("HTTP server error on retrieving incoming request: {}", e);
                            }
                        },
                        _ => unreachable!("unknown poll token."),
                    }
                }
                if do_exit {
                    exit_api_server(api_notifier, &to_api);
                    break;
                }
            }
            info!("http-server thread exits");
            // Keep the Waker alive to match the lifetime of the poll loop above
            drop(waker2);
            Ok(())
        })?;
    Ok((thread, waker))
}
pub fn start_http_thread ( path : & str , api_notifier : Option < Arc < Waker > > , to_api : Sender < Option < ApiRequest > > , from_api : Receiver < ApiResponse > , ) -> Result < ( thread :: JoinHandle < Result < ( ) > > , Arc < Waker > ) > { // Try to remove existed unix domain socket std :: fs :: remove_file ( path ) . unwrap_or_default ( ) ; let socket_path = PathBuf :: from ( path ) ; let mut pool = Poll :: new ( ) ? ; let waker = Arc :: new ( Waker :: new ( pool . registry ( ) , EXIT_TOKEN ) ? ) ; let waker2 = waker . clone ( ) ; let mut server = HttpServer :: new ( socket_path ) . map_err ( | e | { if let ServerError :: IOError ( e ) = e { e } else { Error :: new ( ErrorKind :: Other , format ! ( " " e ) ) } } ) ? ; pool . registry ( ) . register ( & mut SourceFd ( & server . epoll ( ) . as_raw_fd ( ) ) , REQUEST_TOKEN , Interest :: READABLE , ) ? ; let thread = thread :: Builder :: new ( ) . name ( " " . to_string ( ) ) . spawn ( move | | { // Must start the server successfully or just die by panic server . start_server ( ) . unwrap ( ) ; let mut events = Events :: with_capacity ( 100 ) ; let mut do_exit = false ; info ! ( " " ) ; loop { match pool . poll ( & mut events , None ) { Err ( e ) if e . kind ( ) == std :: io :: ErrorKind :: Interrupted => continue , Err ( e ) => { error ! ( " " e ) ; exit_api_server ( api_notifier , & to_api ) ; return Err ( e ) ; } Ok ( _ ) => { } } for event in & events { match event . token ( ) { EXIT_TOKEN => do_exit = true , REQUEST_TOKEN => match server . requests ( ) { Ok ( request_vec ) => { for server_request in request_vec { let reply = server_request . process ( | request | { handle_http_request ( request , api_notifier . clone ( ) , & to_api , & from_api , ) } ) ; // Ignore error when sending response server . respond ( reply ) . unwrap_or_else ( | e | { error ! ( " " e ) } ) ; } } Err ( e ) => { error ! ( " " e ) ; } } , _ => unreachable ! ( " " ) , } } if do_exit { exit_api_server ( api_notifier , & to_api ) ; break ; } } info ! ( " " ) ; // Keep the Waker alive to match the lifetime of the poll loop above drop ( waker2 ) ; Ok ( ( ) ) } ) ? ; Ok ( ( thread , waker ) ) }
Start a HTTP server parsing http requests and send to nydus API server a concrete
request to operate nydus or fetch working status.
Start a HTTP server parsing http requests and send to nydus API server a concrete request to operate nydus or fetch working status .
path
&str
api_notifier
Option<Arc<Waker>>
to_api
Sender<Option<ApiRequest>>
from_api
Receiver<ApiResponse>
path
&str
api_notifier
Option<Arc<Waker>>
to_api
Sender<Option<ApiRequest>>
from_api
Receiver<ApiResponse>