Skip to content

Commit 7e55cb6

Browse files
committed
fix: prevent re-creation instances when only Configuration metadata or status changes
1 parent 25d9ea3 commit 7e55cb6

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
**/obj
33
**/bin
44
**/cobertura.xml
5+
.idea

agent/src/util/config_action.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use akri_shared::{
1616
use futures::{StreamExt, TryStreamExt};
1717
use kube::api::{Api, ListParams, WatchEvent};
1818
use log::{info, trace};
19-
use std::{collections::HashMap, sync::Arc};
19+
use std::{collections::HashMap, option::Option, sync::Arc};
2020
use tokio::sync::{broadcast, mpsc, Mutex};
2121

2222
type ConfigMap = Arc<Mutex<HashMap<String, ConfigInfo>>>;
@@ -34,6 +34,10 @@ pub struct ConfigInfo {
3434
/// Receives notification that all `DiscoveryOperators` threads have completed and a Configuration's Instances
3535
/// can be safely deleted and the associated `DevicePluginServices` terminated.
3636
finished_discovery_receiver: mpsc::Receiver<()>,
37+
/// Tracks the last generation of the `Configuration` resource (i.e. `.metadata.generation`).
38+
/// This is used to determine if the `Configuration` actually changed, or if only the metadata changed.
39+
/// The `.metadata.generation` value is incremented for all changes, except for changes to `.metadata` or `.status`.
40+
last_generation: Option<i64>,
3741
}
3842

3943
/// This handles pre-existing Configurations and invokes an internal method that watches for Configuration events.
@@ -154,6 +158,16 @@ async fn handle_config(
154158
"handle_config - modified Configuration {:?}",
155159
config.metadata.name,
156160
);
161+
let do_recreate = should_recreate_config(&config, config_map.clone())
162+
.await
163+
.unwrap();
164+
if !do_recreate {
165+
trace!(
166+
"handle_config - config {:?} has not changed. ignoring config modified event.",
167+
config.metadata.name,
168+
);
169+
return Ok(());
170+
}
157171
handle_config_delete(kube_interface, &config, config_map.clone()).await?;
158172
tokio::spawn(async move {
159173
handle_config_add(
@@ -196,6 +210,7 @@ async fn handle_config_add(
196210
instance_map: instance_map.clone(),
197211
stop_discovery_sender: stop_discovery_sender.clone(),
198212
finished_discovery_receiver,
213+
last_generation: config.metadata.generation,
199214
};
200215
config_map
201216
.lock()
@@ -276,6 +291,24 @@ async fn handle_config_delete(
276291
Ok(())
277292
}
278293

294+
/// Checks to see if the configuration needs to be recreated.
295+
/// At present, this just checks to see if the `.metadata.generation` has changed.
296+
/// The `.metadata.generation` value is incremented for all changes, except for changes to `.metadata` or `.status`.
297+
async fn should_recreate_config(config: &Configuration, config_map: ConfigMap) -> Result<bool, ()> {
298+
let name = config.metadata.name.clone().unwrap();
299+
let last_generation = config_map.lock().await.get(&name).unwrap().last_generation;
300+
trace!(
301+
"should_recreate_config - checking if config {} needs to be recreated",
302+
name,
303+
);
304+
305+
if config.metadata.generation == last_generation {
306+
return Ok(false);
307+
}
308+
309+
Ok(true)
310+
}
311+
279312
/// This shuts down all a Configuration's Instances and terminates the associated Device Plugins
280313
pub async fn delete_all_instances_in_map(
281314
kube_interface: &impl k8s::KubeInterface,
@@ -341,6 +374,7 @@ mod config_action_tests {
341374
stop_discovery_sender,
342375
instance_map: instance_map.clone(),
343376
finished_discovery_receiver,
377+
last_generation: config.metadata.generation,
344378
},
345379
);
346380
let config_map: ConfigMap = Arc::new(Mutex::new(map));

0 commit comments

Comments
 (0)