pub fn start_hot_reloading(
        &mut self,
        plugin_directory: impl Into<PathBuf>,
    ) -> notify::Result<()> {
        let plugin_directory = plugin_directory.into();

        // Create plugin directory if it doesn't exist.
        std::fs::create_dir_all(&plugin_directory)?;

        // If this is the first call to `start_hot_reloading()`, create a new file system watcher
        // and background thread for loading plugins. For later invocations, the same watcher and
        // thread will be used.
        if self.fs_watcher.is_none() {
            let (tx, rx) = mpsc::channel();
            let fs_watcher = notify::watcher(tx, Duration::from_secs(3)).unwrap();

            let hot_reload_registry = self.inner.clone();
            thread::spawn(move || {
                // Simple helper functions for loading/unloading plugins.
                let maybe_load = |file: &PathBuf| {
                    let mut hot_reload_registry = hot_reload_registry.write().unwrap();
                    if is_library_file(&file) {
                        // Ignore errors.
                        hot_reload_registry.load_plugin(file).ok();
                    }
                };
                let rename = |old_path: &PathBuf, new_path: &PathBuf| {
                    let mut hot_reload_registry = hot_reload_registry.write().unwrap();
                    if let Some(plugin) = hot_reload_registry.get_plugin_by_path(old_path) {
                        hot_reload_registry.update_plugin_path(plugin.name(), new_path);
                    }
                };

                loop {
                    match rx.recv() {
                        Ok(DebouncedEvent::Create(file)) => {
                            maybe_load(&file);
                        }
                        Ok(DebouncedEvent::Remove(file)) => {
                            // We cannot do much when the file is deleted. See issue #10854
                            warn!("a loaded coprocessor plugin is removed. Be aware that original plugin is still running"; "plugin_path" => ?file);
                        }
                        Ok(DebouncedEvent::Rename(old_file, new_file)) => {
                            // If the file is renamed with a different parent directory, we will receive a `Remove` instead.
                            debug_assert!(old_file.parent() == new_file.parent());
                            rename(&old_file, &new_file);
                        }
                        Ok(DebouncedEvent::Write(file)) => {
                            // We cannot do much when the file is deleted. See issue #10854
                            warn!("another process is overwriting a coprocessor plugin while the plugin is loaded. Be aware that original plugin is still running"; "plugin_path" => ?file);
                        }
                        Ok(_) => (),
                        Err(_) => break, // Stop when watcher is dropped.
                    }
                }
            });

            self.fs_watcher = Some(fs_watcher);
        }

        // Register a new directory for hot-reloading.
        if let Some(watcher) = &mut self.fs_watcher {
            watcher.watch(&plugin_directory, RecursiveMode::NonRecursive)?;
        } else {
            // `self.fs_watcher` will never be `None` at this point.
            unreachable!();
        }

        // Load plugins that are already in the directory.
        self.load_plugins_from_dir(&plugin_directory)?;
        Ok(())
    }
/// Hot-reloads plugins from a given directory.
///
/// All plugins that are already present in the directory will be loaded.
/// A background thread is spawned to watch file system events. If the library file of a loaded
/// plugin is deleted, the corresponding plugin is automatically unloaded; if a new library file
/// is placed into the directory, it will be automatically loaded into TiKV's coprocessor plugin
/// system.
///
/// A file will only be loaded if it has the proper file ending of dynamic link libraries for
/// the current platform (`.so` for Linux, `.dylib` for MacOS, `.dll` for Windows).
Hot-reloads plugins from a given directory.
All plugins that are already present in the directory will be loaded.
A background thread is spawned to watch file system events. If the library file of a loaded
plugin is deleted, the corresponding plugin is automatically unloaded; if a new library file
is placed into the directory, it will be automatically loaded into TiKV's coprocessor plugin
system.


Hot - reloads plugins from a given directory . All plugins that are already present in the directory will be loaded . A background thread is spawned to watch file system events . If the library file of a loaded plugin is deleted the corresponding plugin is automatically unloaded ; if a new library file is placed into the directory it will be automatically loaded into TiKV ' s coprocessor plugin system .
pub fn start_hot_reloading(
        &mut self,
        plugin_directory: impl Into<PathBuf>,
    ) -> notify::Result<()> {
        let plugin_directory = plugin_directory.into();
        // Create plugin directory if it doesn't exist.
        std::fs::create_dir_all(&plugin_directory)?;
        // If this is the first call to `start_hot_reloading()`, create a new file system watcher
        // and background thread for loading plugins. For later invocations, the same watcher and
        // thread will be used.
        if self.fs_watcher.is_none() {
            let (tx, rx) = mpsc::channel();
            let fs_watcher = notify::watcher(tx, Duration::from_secs(3)).unwrap();
            let hot_reload_registry = self.inner.clone();
            thread::spawn(move || {
                // Simple helper functions for loading/unloading plugins.
                let maybe_load = |file: &PathBuf| {
                    let mut hot_reload_registry = hot_reload_registry.write().unwrap();
                    if is_library_file(&file) {
                        // Ignore errors.
                        hot_reload_registry.load_plugin(file).ok();
                    }
                };
                let rename = |old_path: &PathBuf, new_path: &PathBuf| {
                    let mut hot_reload_registry = hot_reload_registry.write().unwrap();
                    if let Some(plugin) = hot_reload_registry.get_plugin_by_path(old_path) {
                        hot_reload_registry.update_plugin_path(plugin.name(), new_path);
                    }
                };
                loop {
                    match rx.recv() {
                        Ok(DebouncedEvent::Create(file)) => {
                            maybe_load(&file);
                        }
                        Ok(DebouncedEvent::Remove(file)) => {
                            // We cannot do much when the file is deleted. See issue #10854
                            warn!("a loaded coprocessor plugin is removed. Be aware that original plugin is still running"; "plugin_path" => ?file);
                        }
                        Ok(DebouncedEvent::Rename(old_file, new_file)) => {
                            // If the file is renamed with a different parent directory, we will receive a `Remove` instead.
                            debug_assert!(old_file.parent() == new_file.parent());
                            rename(&old_file, &new_file);
                        }
                        Ok(DebouncedEvent::Write(file)) => {
                            // We cannot do much when the file is deleted. See issue #10854
                            warn!("another process is overwriting a coprocessor plugin while the plugin is loaded. Be aware that original plugin is still running"; "plugin_path" => ?file);
                        }
                        Ok(_) => (),
                        Err(_) => break, // Stop when watcher is dropped.
                    }
                }
            });
            self.fs_watcher = Some(fs_watcher);
        }
        // Register a new directory for hot-reloading.
        if let Some(watcher) = &mut self.fs_watcher {
            watcher.watch(&plugin_directory, RecursiveMode::NonRecursive)?;
        } else {
            // `self.fs_watcher` will never be `None` at this point.
            unreachable!();
        }
        // Load plugins that are already in the directory.
        self.load_plugins_from_dir(&plugin_directory)?;
        Ok(())
    }
pub fn start_hot_reloading ( & mut self , plugin_directory : impl Into < PathBuf > , ) -> notify :: Result < ( ) > { let plugin_directory = plugin_directory . into ( ) ; // Create plugin directory if it doesn't exist. std :: fs :: create_dir_all ( & plugin_directory ) ? ; // If this is the first call to `start_hot_reloading()`, create a new file system watcher // and background thread for loading plugins. For later invocations, the same watcher and // thread will be used. if self . fs_watcher . is_none ( ) { let ( tx , rx ) = mpsc :: channel ( ) ; let fs_watcher = notify :: watcher ( tx , Duration :: from_secs ( 3 ) ) . unwrap ( ) ; let hot_reload_registry = self . inner . clone ( ) ; thread :: spawn ( move | | { // Simple helper functions for loading/unloading plugins. let maybe_load = | file : & PathBuf | { let mut hot_reload_registry = hot_reload_registry . write ( ) . unwrap ( ) ; if is_library_file ( & file ) { // Ignore errors. hot_reload_registry . load_plugin ( file ) . ok ( ) ; } } ; let rename = | old_path : & PathBuf , new_path : & PathBuf | { let mut hot_reload_registry = hot_reload_registry . write ( ) . unwrap ( ) ; if let Some ( plugin ) = hot_reload_registry . get_plugin_by_path ( old_path ) { hot_reload_registry . update_plugin_path ( plugin . name ( ) , new_path ) ; } } ; loop { match rx . recv ( ) { Ok ( DebouncedEvent :: Create ( file ) ) => { maybe_load ( & file ) ; } Ok ( DebouncedEvent :: Remove ( file ) ) => { // We cannot do much when the file is deleted. See issue #10854 warn ! ( " " " " file ) ; } Ok ( DebouncedEvent :: Rename ( old_file , new_file ) ) => { // If the file is renamed with a different parent directory, we will receive a `Remove` instead. debug_assert ! ( old_file parent ( ) new_file parent ( ) ) ; rename ( & old_file , & new_file ) ; } Ok ( DebouncedEvent :: Write ( file ) ) => { // We cannot do much when the file is deleted. See issue #10854 warn ! ( " " " " file ) ; } Ok ( _ ) => ( ) , Err ( _ ) => break , // Stop when watcher is dropped. } } } ) ; self . fs_watcher = Some ( fs_watcher ) ; } // Register a new directory for hot-reloading. if let Some ( watcher ) = & mut self . fs_watcher { watcher . watch ( & plugin_directory , RecursiveMode :: NonRecursive ) ? ; } else { // `self.fs_watcher` will never be `None` at this point. unreachable ! ( ) ; } // Load plugins that are already in the directory. self . load_plugins_from_dir ( & plugin_directory ) ? ; Ok ( ( ) ) }
Hot-reloads plugins from a given directory.
Hot - reloads plugins from a given directory .
&mut self
plugin_directory
impl Into<PathBuf>