MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / spawn_reload_worker

Method spawn_reload_worker

crates/openshell-server/src/tls.rs:127–244  ·  view source on GitHub ↗

Spawn a background worker that watches the parent directories of the cert, key, and CA files and calls [`reload`](Self::reload) when changes are detected. A 1-second debounce window coalesces rapid filesystem events (such as Kubernetes Secret volume atomic swaps) into a single reload. If reload fails, the old config is preserved and a warning is logged. The worker exits when the `shutdown` watch

(
        &self,
        mut shutdown: watch::Receiver<bool>,
    )

Source from the content-addressed store, hash-verified

125 /// gateway to perform a graceful shutdown without orphaned reload
126 /// tasks.
127 pub fn spawn_reload_worker(
128 &self,
129 mut shutdown: watch::Receiver<bool>,
130 ) -> tokio::task::JoinHandle<()> {
131 if self.reload_spawned.swap(true, Ordering::Relaxed) {
132 warn!("TLS certificate reload worker already spawned, ignoring duplicate call");
133 return tokio::spawn(async {});
134 }
135
136 let this = self.clone();
137
138 // Collect unique parent directories to watch.
139 let cert_dir = self.cert_path.parent().unwrap_or_else(|| Path::new("."));
140 let key_dir = self.key_path.parent().unwrap_or_else(|| Path::new("."));
141 let mut dirs = vec![cert_dir.to_path_buf()];
142 if key_dir != cert_dir {
143 dirs.push(key_dir.to_path_buf());
144 }
145 if let Some(ref ca) = self.client_ca_path {
146 let ca_dir = ca.parent().unwrap_or_else(|| Path::new("."));
147 if ca_dir != cert_dir && ca_dir != key_dir {
148 dirs.push(ca_dir.to_path_buf());
149 }
150 }
151
152 let debounce = Duration::from_secs(1);
153
154 tokio::spawn(async move {
155 let (tx, mut rx) = mpsc::unbounded_channel();
156
157 // recommended_watcher runs its own thread; we bridge events into
158 // the tokio runtime via the unbounded mpsc channel.
159 let mut watcher = match notify::recommended_watcher(
160 move |res: std::result::Result<Event, notify::Error>| {
161 if let Ok(event) = res
162 && matches!(event.kind, EventKind::Modify(_) | EventKind::Create(_))
163 {
164 let _ = tx.send(());
165 }
166 },
167 ) {
168 Ok(w) => w,
169 Err(e) => {
170 warn!(error = %e, "Failed to start TLS cert file watcher, hot-reload disabled");
171 return;
172 }
173 };
174
175 for dir in &dirs {
176 if let Err(e) = watcher.watch(dir, RecursiveMode::NonRecursive) {
177 warn!(error = %e, dir = %dir.display(), "Failed to watch TLS cert directory, hot-reload disabled");
178 return;
179 }
180 }
181
182 info!(?dirs, "TLS certificate file watcher started");
183
184 // Event loop with manual debounce.

Callers 3

run_serverFunction · 0.80

Calls 2

pushMethod · 0.80
spawnFunction · 0.50