fn run(mut self) -> ExitStatus {
        while !self.repo.all_have_finished() {
            // Ingest updates
            let received_events = self.repo.get_events();
            debug!("Applying events... {:?}", received_events);
            match (self.status, signal_handling::is_sigterm_received()) {
                (LifecycleStatus::Running, true) => {
                    warn!("1. SIGTERM received");
                    self.repo
                        .send_ev(Event::ShuttingDownInitiated(ShuttingDown::Gracefuly));
                }
                (LifecycleStatus::ShuttingDown(ShuttingDown::Gracefuly), true) => {
                    warn!("2. SIGTERM received");
                    self.repo
                        .send_ev(Event::ShuttingDownInitiated(ShuttingDown::Forcefuly));
                }
                _ => {}
            }
            // Handling of the received events and commands:
            let produced_events = received_events
                .into_iter()
                .map(|ev| self.handle_event(ev))
                .flatten()
                .collect::<Vec<Event>>();
            debug!("Produced events: {:?}", produced_events);
            // Producing commands which will be applied in the next iteration
            let next_evs: Vec<Event> = self
                .repo
                .services
                .iter()
                .map(|(_s_name, sh)| sh.next(&self.repo, self.status))
                .flatten()
                .chain(reaper::run(&self.repo, MAX_PROCESS_REAPS_ITERS))
                .collect();
            debug!("Next evs: {:?}", next_evs);
            // Dispatch everything via the bus. Since the bus is run by another thread,
            // the next_evs might not arrive in the next batch, leading to possibly duplicated
            // commands.
            produced_events
                .into_iter()
                .chain(next_evs)
                .for_each(|ev| self.repo.send_ev(ev));

            std::thread::sleep(Duration::from_millis(300));
        }

        debug!("All services have finished");
        // If we're the init system, let's be sure that everything stops before exiting.
        let init_pid = unistd::Pid::from_raw(1);
        // TODO: Test (probably via docker).
        if unistd::getpid() == init_pid {
            let all_processes = unistd::Pid::from_raw(-1);
            let _res = signal::kill(all_processes, signal::SIGTERM);
            thread::sleep(Duration::from_secs(3));
            let _res = signal::kill(all_processes, signal::SIGKILL);
        }

        self.repo
            .send_ev(Event::ShuttingDownInitiated(ShuttingDown::Gracefuly));
        if self.repo.any_finished_failed() {
            ExitStatus::SomeServiceFailed
        } else {
            ExitStatus::Successful
        }
    }
/// Blocking call.
/// This function will run the services and reap dead pids.
Blocking call.
This function will run the services and reap dead pids.
Blocking call . This function will run the services and reap dead pids .
fn run(mut self) -> ExitStatus {
        while !self.repo.all_have_finished() {
            // Ingest updates
            let received_events = self.repo.get_events();
            debug!("Applying events... {:?}", received_events);
            match (self.status, signal_handling::is_sigterm_received()) {
                (LifecycleStatus::Running, true) => {
                    warn!("1. SIGTERM received");
                    self.repo
                        .send_ev(Event::ShuttingDownInitiated(ShuttingDown::Gracefuly));
                }
                (LifecycleStatus::ShuttingDown(ShuttingDown::Gracefuly), true) => {
                    warn!("2. SIGTERM received");
                    self.repo
                        .send_ev(Event::ShuttingDownInitiated(ShuttingDown::Forcefuly));
                }
                _ => {}
            }
            // Handling of the received events and commands:
            let produced_events = received_events
                .into_iter()
                .map(|ev| self.handle_event(ev))
                .flatten()
                .collect::<Vec<Event>>();
            debug!("Produced events: {:?}", produced_events);
            // Producing commands which will be applied in the next iteration
            let next_evs: Vec<Event> = self
                .repo
                .services
                .iter()
                .map(|(_s_name, sh)| sh.next(&self.repo, self.status))
                .flatten()
                .chain(reaper::run(&self.repo, MAX_PROCESS_REAPS_ITERS))
                .collect();
            debug!("Next evs: {:?}", next_evs);
            // Dispatch everything via the bus. Since the bus is run by another thread,
            // the next_evs might not arrive in the next batch, leading to possibly duplicated
            // commands.
            produced_events
                .into_iter()
                .chain(next_evs)
                .for_each(|ev| self.repo.send_ev(ev));
            std::thread::sleep(Duration::from_millis(300));
        }
        debug!("All services have finished");
        // If we're the init system, let's be sure that everything stops before exiting.
        let init_pid = unistd::Pid::from_raw(1);
        // TODO: Test (probably via docker).
        if unistd::getpid() == init_pid {
            let all_processes = unistd::Pid::from_raw(-1);
            let _res = signal::kill(all_processes, signal::SIGTERM);
            thread::sleep(Duration::from_secs(3));
            let _res = signal::kill(all_processes, signal::SIGKILL);
        }
        self.repo
            .send_ev(Event::ShuttingDownInitiated(ShuttingDown::Gracefuly));
        if self.repo.any_finished_failed() {
            ExitStatus::SomeServiceFailed
        } else {
            ExitStatus::Successful
        }
    }
fn run ( mut self ) -> ExitStatus { while ! self . repo . all_have_finished ( ) { // Ingest updates let received_events = self . repo . get_events ( ) ; debug ! ( " " received_events ) ; match ( self . status , signal_handling :: is_sigterm_received ( ) ) { ( LifecycleStatus :: Running , true ) => { warn ! ( " " ) ; self . repo . send_ev ( Event :: ShuttingDownInitiated ( ShuttingDown :: Gracefuly ) ) ; } ( LifecycleStatus :: ShuttingDown ( ShuttingDown :: Gracefuly ) , true ) => { warn ! ( " " ) ; self . repo . send_ev ( Event :: ShuttingDownInitiated ( ShuttingDown :: Forcefuly ) ) ; } _ => { } } // Handling of the received events and commands: let produced_events = received_events . into_iter ( ) . map ( | ev | self . handle_event ( ev ) ) . flatten ( ) . collect :: < Vec < Event > > ( ) ; debug ! ( " " produced_events ) ; // Producing commands which will be applied in the next iteration let next_evs : Vec < Event > = self . repo . services . iter ( ) . map ( | ( _s_name , sh ) | sh . next ( & self . repo , self . status ) ) . flatten ( ) . chain ( reaper :: run ( & self . repo , MAX_PROCESS_REAPS_ITERS ) ) . collect ( ) ; debug ! ( " " next_evs ) ; // Dispatch everything via the bus. Since the bus is run by another thread, // the next_evs might not arrive in the next batch, leading to possibly duplicated // commands. produced_events . into_iter ( ) . chain ( next_evs ) . for_each ( | ev | self . repo . send_ev ( ev ) ) ; std :: thread :: sleep ( Duration :: from_millis ( 300 ) ) ; } debug ! ( " " ) ; // If we're the init system, let's be sure that everything stops before exiting. let init_pid = unistd :: Pid :: from_raw ( 1 ) ; // TODO: Test (probably via docker). if unistd :: getpid ( ) == init_pid { let all_processes = unistd :: Pid :: from_raw ( - 1 ) ; let _res = signal :: kill ( all_processes , signal :: SIGTERM ) ; thread :: sleep ( Duration :: from_secs ( 3 ) ) ; let _res = signal :: kill ( all_processes , signal :: SIGKILL ) ; } self . repo . send_ev ( Event :: ShuttingDownInitiated ( ShuttingDown :: Gracefuly ) ) ; if self . repo . any_finished_failed ( ) { ExitStatus :: SomeServiceFailed } else { ExitStatus :: Successful } }
Blocking call.
Blocking call .
mut self
mut self