changeset 603:b45b8b4cf0f5 rust

get rid of lazy_static, config is passed around better use of threadpool for sensors readings are no longer options
author Matt Johnston <matt@ucc.asn.au>
date Thu, 16 Feb 2017 23:19:12 +0800
parents 613f114feb4b
children 278f1002b5c7
files rust/Cargo.lock rust/Cargo.toml rust/src/fridge.rs rust/src/main.rs rust/src/sensor.rs rust/src/types.rs
diffstat 6 files changed, 77 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/rust/Cargo.lock	Thu Feb 16 23:17:51 2017 +0800
+++ b/rust/Cargo.lock	Thu Feb 16 23:19:12 2017 +0800
@@ -6,7 +6,6 @@
  "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/rust/Cargo.toml	Thu Feb 16 23:17:51 2017 +0800
+++ b/rust/Cargo.toml	Thu Feb 16 23:19:12 2017 +0800
@@ -15,7 +15,6 @@
 docopt = "0.7"
 rustc-serialize = "0.3"
 time = "0.1"
-lazy_static = "0.2"
 
 [dependencies.toml]
 git = "https://github.com/alexcrichton/toml-rs"
--- a/rust/src/fridge.rs	Thu Feb 16 23:17:51 2017 +0800
+++ b/rust/src/fridge.rs	Thu Feb 16 23:19:12 2017 +0800
@@ -10,10 +10,9 @@
 use tokio_core::reactor::{Timeout,Handle};
 use futures::sync::{mpsc};
 
+use ::Config;
 use types::*;
 
-use ::rigid_config;
-
 #[derive(Debug)]
 pub enum Message {
     Sensor {wort: Option<f32>, fridge: Option<f32>},
@@ -23,6 +22,7 @@
 
 pub struct Fridge {
     params: Params,
+    config: Config,
     temp_wort: Option<f32>,
     temp_fridge: Option<f32>,
 
@@ -51,9 +51,10 @@
 }
 
 impl Fridge {
-    pub fn new(nowait: bool, p: Params, handle: &Handle) -> Fridge {
+    pub fn new(config: &Config, nowait: bool, p: Params, handle: &Handle) -> Fridge {
         let (s, r) = mpsc::channel(1);
         let mut f = Fridge { 
+            config: config.clone(),
             params: p,
             temp_wort: None,
             temp_fridge: None,
@@ -65,7 +66,7 @@
             last_off_time: Instant::now(),
         };
         if nowait {
-            f.last_off_time -= Duration::new(rigid_config.FRIDGE_DELAY, 100);
+            f.last_off_time -= Duration::new(config.FRIDGE_DELAY, 100);
         }
         f.tick();
         f
--- a/rust/src/main.rs	Thu Feb 16 23:17:51 2017 +0800
+++ b/rust/src/main.rs	Thu Feb 16 23:19:12 2017 +0800
@@ -7,9 +7,6 @@
 extern crate time;
 
 #[macro_use]
-extern crate lazy_static;
-
-#[macro_use]
 extern crate serde_derive;
 extern crate serde;
 
@@ -33,28 +30,32 @@
 use types::*;
 use config::Config;
 
-fn run(nowait: bool, testmode: bool) {
+fn run(config: &Config, nowait: bool, testmode: bool) {
 
     let mut core = Core::new().unwrap();
     let handle = core.handle();
 
     let mut paramh = ParamHolder::new();
-    let mut fridge = fridge::Fridge::new(nowait, paramh.p, &handle);
+    let mut fridge = fridge::Fridge::new(&config, nowait, paramh.p, &handle);
 
     let (fridge_reading_s, fridge_reading_r) = mpsc::channel(1);
     let fridge_reading_r = fridge_reading_r.map_err(|_| io::Error::new(io::ErrorKind::Other, "Problem with fridge_reading_r channel"));
 
     let sensor_stream = if testmode {
-        sensor::TestSensor::stream(&handle)
+        sensor::TestSensor::new(config).stream(&handle)
     } else {
-        sensor::OneWireSensor::stream(&handle)
+        sensor::OneWireSensor::new(config).stream(&handle)
     };
 
     // Send the sensors of interest to the fridge (fridge_reading_s),
     // while streaming them all to the web sender.
     let s = sensor_stream.map(|r| {
         debug!("sensors {:?}", r);
-        let t = fridge_reading_s.clone().send(fridge::Message::Sensor{wort: r.wort(), fridge: r.fridge()})
+        let msg = fridge::Message::Sensor {
+            wort: r.get_temp(&config.WORT_NAME), 
+            fridge: r.get_temp(&config.FRIDGE_NAME)
+        };
+        let t = fridge_reading_s.clone().send(msg)
                     .map(|_| ())
                     .map_err(|e| {
                         warn!("Send error in fridge_reading_s: {}", e.to_string());
@@ -139,7 +140,7 @@
 }
 
 fn load_config() -> Config {
-    let mut nconfig = config::Config::default();
+    let nconfig = config::Config::default();
 
     let conf_filename = "tempserver.conf";
     nconfig.merge_file(conf_filename)
@@ -149,10 +150,6 @@
     })
 }
 
-lazy_static! {
-    static ref rigid_config: Config = load_config();
-}
-
 fn main() {
 
     let args = handle_args();
@@ -162,14 +159,14 @@
     info!("wort-templog");
     debug!("debug mode");
 
+    let config = load_config();
+
     if args.flag_thisconf {
         println!("Current configuration:\n\n{}",
-            rigid_config.to_toml_string());
+            config.to_toml_string());
         std::process::exit(0);
     }
 
-
-
-    run(args.flag_nowait, args.flag_test);
+    run(&config, args.flag_nowait, args.flag_test);
 }
 
--- a/rust/src/sensor.rs	Thu Feb 16 23:17:51 2017 +0800
+++ b/rust/src/sensor.rs	Thu Feb 16 23:19:12 2017 +0800
@@ -8,40 +8,59 @@
 use std::io::{Read,BufReader,BufRead};
 use std::path::PathBuf;
 use std::error::Error;
+use std::sync::Arc;
 
 use tokio_core::reactor::Interval;
 use tokio_core::reactor::Handle;
 use futures::Stream;
 use types::*;
+use ::Config;
 
-use ::rigid_config;
+
 
 pub trait Sensor {
-    fn stream(handle: &Handle)
+    fn stream(&self, handle: &Handle)
         -> Box<Stream<Item=Readings, Error=io::Error>>;
 }
 
+#[derive(Clone)]
 pub struct OneWireSensor {
+    config: Arc<Config>,
 }
 
 impl OneWireSensor {
-    fn new() -> OneWireSensor {
+    pub fn new(config: &Config) -> Self {
         OneWireSensor {
+            config: Arc::new(config.clone()),
         }
     }
 
-    fn step() -> Readings {
+    fn step(&self) -> Readings {
         let mut r = Readings::new();
 
+        if let Ok(names) = self.sensor_names() {
+            for n in &names {
+                match self.read_sensor(n) {
+                    Ok(s) => r.add(n, s),
+                    Err(e) => debug!("Error reading sensors {}: {}", n, e)
+                }
+            }
+        }
 
-        r.add("ambient", Some(31.2));
-        r.add("wort_todo", Some(8.0));
         debug!("sensor step {:?}", r);
         r
     }
 
+    fn read_sensor(&self, n: &str) -> Result<f32, Box<Error>> {
+        let mut path = PathBuf::from(&self.config.SENSOR_BASE_DIR);
+        path.push(n);
+        path.push("w1_slave");
+        let f = BufReader::new(File::open(path)?);
+        Ok(3.4)
+    }
+
     fn sensor_names(&self) -> Result<Vec<String>, Box<Error>> {
-        let mut path = PathBuf::from(&rigid_config.SENSOR_BASE_DIR);
+        let mut path = PathBuf::from(&self.config.SENSOR_BASE_DIR);
         path.push("w1_master_slaves");
 
         let f = BufReader::new(File::open(path)?);
@@ -50,37 +69,39 @@
     }
 }
 
-// does this need to be static?
-lazy_static! {
-    static ref thread_pool : futures_cpupool::CpuPool = futures_cpupool::CpuPool::new(3); // TODO: how many?
-}
+impl Sensor for OneWireSensor {
+
+    fn stream(&self, handle: &Handle) -> Box<Stream<Item=Readings, Error=io::Error>> {
+        let pool = futures_cpupool::CpuPool::new(4); // TODO: how many?
 
-impl Sensor for OneWireSensor {
-    fn stream(handle: &Handle)
-        -> Box<Stream<Item=Readings, Error=io::Error>> {
-        let mut s = OneWireSensor::new();
-
-        let dur = Duration::new(rigid_config.SENSOR_SLEEP,0);
+        let dur = Duration::new(self.config.SENSOR_SLEEP,0);
+        let s = Arc::new(self.clone());
         Interval::new(dur, handle).unwrap()
-            .and_then(|()| {
-                thread_pool.spawn_fn(|| Ok(Self::step()))
-            }).boxed()
+            .and_then(move |()| {
+                let a = s.clone();
+                pool.spawn_fn(move || Ok(a.step()))
+            })
+            .boxed()
     }
 }
 
+#[derive(Clone)]
 pub struct TestSensor {
+    config: Config,
 }
 
 impl TestSensor {
-    pub fn new() -> Self {
-        TestSensor {}
+    pub fn new(config: &Config) -> Self {
+        TestSensor {
+            config: config.clone(),
+        }
     }
 
-    fn step(&mut self) -> Readings {
+    fn test_step() -> Readings {
         let mut r = Readings::new();
-        r.add("ambient", Some(31.2));
-        r.add("wort", Some(Self::try_read("test_wort.txt").unwrap_or_else(|_| 18.0)));
-        r.add("fridge", Some(Self::try_read("test_fridge.txt").unwrap_or_else(|_| 20.0)));
+        r.add("ambient", 31.2);
+        r.add("wort", Self::try_read("test_wort.txt").unwrap_or_else(|_| 18.0));
+        r.add("fridge", Self::try_read("test_fridge.txt").unwrap_or_else(|_| 20.0));
         r
     }
 
@@ -92,14 +113,14 @@
 }
 
 impl Sensor for TestSensor {
-    fn stream(handle: &Handle)
+    fn stream(&self, handle: &Handle)
         -> Box<Stream<Item=Readings, Error=io::Error>> {
-        let mut s = TestSensor::new();
 
-        let dur = Duration::new(rigid_config.SENSOR_SLEEP,0);
-        Interval::new(dur, handle).unwrap().map(move |()| {
-            s.step()
-        }).boxed()
+        let dur = Duration::new(self.config.SENSOR_SLEEP,0);
+        Interval::new(dur, handle).unwrap()
+            .and_then(move |()| {
+                Ok(Self::test_step())
+            }).boxed()
     }
 }
 
--- a/rust/src/types.rs	Thu Feb 16 23:17:51 2017 +0800
+++ b/rust/src/types.rs	Thu Feb 16 23:19:12 2017 +0800
@@ -46,7 +46,7 @@
 
 #[derive(Debug)]
 pub struct Readings {
-    temps: HashMap<String, Option<f32>>,
+    pub temps: HashMap<String, f32>,
 }
 
 impl Readings {
@@ -56,29 +56,12 @@
         }
     }
 
-    pub fn add(&mut self, name: &str, v: Option<f32>) {
-        if let Some(prev) = self.temps.insert(name.to_string(), v) {
-            warn!("Replaced existing reading '{}' {:?} -> {:?}",
-                name, prev, v);
-        }
+    pub fn add(&mut self, name: &str, v: f32) {
+        self.temps.insert(name.to_string(), v);
     }
 
-    pub fn fridge(&self) -> Option<f32> {
-        if let Some(t) = self.temps.get("fridge") {
-            t.clone()
-        } else {
-            warn!("No fridge reading was added");
-            None
-        }
-    }
-
-    pub fn wort(&self) -> Option<f32> {
-        if let Some(t) = self.temps.get("wort") {
-            t.clone()
-        } else {
-            warn!("No wort reading was added");
-            None
-        }
+    pub fn get_temp(&self, name: &str) -> Option<f32> {
+        self.temps.get(name).map(|f| *f)
     }
 }