Skip to content
Snippets Groups Projects
startup.rs 3.24 KiB
Newer Older
  • Learn to ignore specific revisions
  • use conduit::{debug, debug_info, error, implement, info, Err, Result};
    
    use ruma::events::room::message::RoomMessageEventContent;
    use tokio::time::{sleep, Duration};
    
    /// Possibly spawn the terminal console at startup if configured.
    #[implement(super::Service)]
    pub(super) async fn console_auto_start(&self) {
    	#[cfg(feature = "console")]
    	if self.services.server.config.admin_console_automatic {
    		// Allow more of the startup sequence to execute before spawning
    		tokio::task::yield_now().await;
    		self.console.start().await;
    	}
    }
    
    /// Shutdown the console when the admin worker terminates.
    #[implement(super::Service)]
    pub(super) async fn console_auto_stop(&self) {
    	#[cfg(feature = "console")]
    	self.console.close().await;
    }
    
    /// Execute admin commands after startup
    #[implement(super::Service)]
    
    pub(super) async fn startup_execute(&self) -> Result<()> {
    	// List of comamnds to execute
    	let commands = &self.services.server.config.admin_execute;
    
    	// Determine if we're running in smoketest-mode which will change some behaviors
    	let smoketest = self.services.server.config.test.contains("smoke");
    
    	// When true, errors are ignored and startup continues.
    	let errors = !smoketest && self.services.server.config.admin_execute_errors_ignore;
    
    	//TODO: remove this after run-states are broadcast
    	sleep(Duration::from_millis(500)).await;
    
    	for (i, command) in commands.iter().enumerate() {
    		if let Err(e) = self.startup_execute_command(i, command.clone()).await {
    			if !errors {
    				return Err(e);
    			}
    		}
    
    
    		tokio::task::yield_now().await;
    	}
    
    
    	// The smoketest functionality is placed here for now and simply initiates
    	// shutdown after all commands have executed.
    
    	if smoketest {
    
    		debug_info!("Smoketest mode. All commands complete. Shutting down now...");
    		self.services
    			.server
    			.shutdown()
    
    			.inspect_err(error::inspect_log)
    			.expect("Error shutting down from smoketest");
    
    }
    
    /// Execute one admin command after startup
    #[implement(super::Service)]
    
    async fn startup_execute_command(&self, i: usize, command: String) -> Result<()> {
    
    	debug!("Startup command #{i}: executing {command:?}");
    
    	match self.command_in_place(command, None).await {
    		Ok(Some(output)) => Self::startup_command_output(i, &output),
    
    		Err(output) => Self::startup_command_error(i, &output),
    		Ok(None) => {
    			info!("Startup command #{i} completed (no output).");
    			Ok(())
    		},
    
    	}
    }
    
    #[cfg(feature = "console")]
    #[implement(super::Service)]
    
    fn startup_command_output(i: usize, content: &RoomMessageEventContent) -> Result<()> {
    	debug_info!("Startup command #{i} completed:");
    	super::console::print(content.body());
    	Ok(())
    }
    
    #[cfg(feature = "console")]
    #[implement(super::Service)]
    fn startup_command_error(i: usize, content: &RoomMessageEventContent) -> Result<()> {
    	super::console::print_err(content.body());
    	Err!(debug_error!("Startup command #{i} failed."))
    
    }
    
    #[cfg(not(feature = "console"))]
    #[implement(super::Service)]
    
    fn startup_command_output(i: usize, content: &RoomMessageEventContent) -> Result<()> {
    
    	info!("Startup command #{i} completed:\n{:#?}", content.body());
    
    	Ok(())
    }
    
    #[cfg(not(feature = "console"))]
    #[implement(super::Service)]
    fn startup_command_error(i: usize, content: &RoomMessageEventContent) -> Result<()> {
    	Err!(error!("Startup command #{i} failed:\n{:#?}", content.body()))