Bladeren bron

fix: hot-reload for client and server both present

Yujia Qiao 4 jaren geleden
bovenliggende
commit
d1fdef5d56
2 gewijzigde bestanden met toevoegingen van 90 en 14 verwijderingen
  1. 18 1
      src/config.rs
  2. 72 13
      src/config_watcher.rs

+ 18 - 1
src/config.rs

@@ -20,7 +20,7 @@ impl Default for TransportType {
     }
 }
 
-#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
 pub struct ClientServiceConfig {
     #[serde(rename = "type", default = "default_service_type")]
     pub service_type: ServiceType,
@@ -30,6 +30,15 @@ pub struct ClientServiceConfig {
     pub token: Option<String>,
 }
 
+impl ClientServiceConfig {
+    pub fn with_name(name: &str) -> ClientServiceConfig {
+        ClientServiceConfig {
+            name: name.to_string(),
+            ..Default::default()
+        }
+    }
+}
+
 #[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
 pub enum ServiceType {
     #[serde(rename = "tcp")]
@@ -58,6 +67,14 @@ pub struct ServerServiceConfig {
     pub token: Option<String>,
 }
 
+impl ServerServiceConfig {
+    pub fn with_name(name: &str) -> ServerServiceConfig {
+        ServerServiceConfig {
+            name: name.to_string(),
+            ..Default::default()
+        }
+    }
+}
 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
 pub struct TlsConfig {
     pub hostname: Option<String>,

+ 72 - 13
src/config_watcher.rs

@@ -190,34 +190,40 @@ async fn config_watcher(
 
 fn calculate_events(old: &Config, new: &Config) -> Vec<ConfigChange> {
     if old == new {
-        vec![]
-    } else if old.server != new.server {
+        return vec![];
+    }
+
+    let mut ret = vec![];
+
+    if old.server != new.server {
         if old.server.is_some() != new.server.is_some() {
-            vec![ConfigChange::General(Box::new(new.clone()))]
+            return vec![ConfigChange::General(Box::new(new.clone()))];
         } else {
             match calculate_instance_config_events(
                 old.server.as_ref().unwrap(),
                 new.server.as_ref().unwrap(),
             ) {
-                Some(v) => v,
-                None => vec![ConfigChange::General(Box::new(new.clone()))],
+                Some(mut v) => ret.append(&mut v),
+                None => return vec![ConfigChange::General(Box::new(new.clone()))],
             }
         }
-    } else if old.client != new.client {
+    }
+
+    if old.client != new.client {
         if old.client.is_some() != new.client.is_some() {
-            vec![ConfigChange::General(Box::new(new.clone()))]
+            return vec![ConfigChange::General(Box::new(new.clone()))];
         } else {
             match calculate_instance_config_events(
                 old.client.as_ref().unwrap(),
                 new.client.as_ref().unwrap(),
             ) {
-                Some(v) => v,
-                None => vec![ConfigChange::General(Box::new(new.clone()))],
+                Some(mut v) => ret.append(&mut v),
+                None => return vec![ConfigChange::General(Box::new(new.clone()))],
             }
         }
-    } else {
-        vec![]
     }
+
+    ret
 }
 
 // None indicates a General change needed
@@ -335,8 +341,31 @@ mod test {
                     client: None,
                 },
             },
+            Test {
+                old: Config {
+                    server: Some(ServerConfig {
+                        services: collection!(String::from("foo1") => ServerServiceConfig::with_name("foo1"), String::from("foo2") => ServerServiceConfig::with_name("foo2")),
+                        ..Default::default()
+                    }),
+                    client: Some(ClientConfig {
+                        services: collection!(String::from("foo1") => ClientServiceConfig::with_name("foo1"), String::from("foo2") => ClientServiceConfig::with_name("foo2")),
+                        ..Default::default()
+                    }),
+                },
+                new: Config {
+                    server: Some(ServerConfig {
+                        services: collection!(String::from("bar1") => ServerServiceConfig::with_name("bar1"), String::from("foo2") => ServerServiceConfig::with_name("foo2")),
+                        ..Default::default()
+                    }),
+                    client: Some(ClientConfig {
+                        services: collection!(String::from("bar1") => ClientServiceConfig::with_name("bar1"), String::from("bar2") => ClientServiceConfig::with_name("bar2")),
+                        ..Default::default()
+                    }),
+                },
+            },
         ];
-        let expected = [
+
+        let mut expected = [
             vec![ConfigChange::General(Box::new(tests[0].new.clone()))],
             vec![ConfigChange::General(Box::new(tests[1].new.clone()))],
             vec![ConfigChange::ServiceChange(ServiceChange::ServerAdd(
@@ -345,12 +374,42 @@ mod test {
             vec![ConfigChange::ServiceChange(ServiceChange::ServerDelete(
                 String::from("foo"),
             ))],
+            vec![
+                ConfigChange::ServiceChange(ServiceChange::ServerDelete(String::from("foo1"))),
+                ConfigChange::ServiceChange(ServiceChange::ServerAdd(
+                    tests[4].new.server.as_ref().unwrap().services["bar1"].clone(),
+                )),
+                ConfigChange::ServiceChange(ServiceChange::ClientDelete(String::from("foo1"))),
+                ConfigChange::ServiceChange(ServiceChange::ClientDelete(String::from("foo2"))),
+                ConfigChange::ServiceChange(ServiceChange::ClientAdd(
+                    tests[4].new.client.as_ref().unwrap().services["bar1"].clone(),
+                )),
+                ConfigChange::ServiceChange(ServiceChange::ClientAdd(
+                    tests[4].new.client.as_ref().unwrap().services["bar2"].clone(),
+                )),
+            ],
         ];
 
         assert_eq!(tests.len(), expected.len());
 
         for i in 0..tests.len() {
-            let actual = calculate_events(&tests[i].old, &tests[i].new);
+            let mut actual = calculate_events(&tests[i].old, &tests[i].new);
+
+            let get_key = |x: &ConfigChange| -> String {
+                match x {
+                    ConfigChange::General(_) => String::from("g"),
+                    ConfigChange::ServiceChange(sc) => match sc {
+                        ServiceChange::ClientAdd(c) => "c_add_".to_owned() + &c.name,
+                        ServiceChange::ClientDelete(s) => "c_del_".to_owned() + s,
+                        ServiceChange::ServerAdd(c) => "s_add_".to_owned() + &c.name,
+                        ServiceChange::ServerDelete(s) => "s_del_".to_owned() + s,
+                    },
+                }
+            };
+
+            actual.sort_by_cached_key(get_key);
+            expected[i].sort_by_cached_key(get_key);
+
             assert_eq!(actual, expected[i]);
         }
     }