diff py/params.py @ 551:9499bd2f344b

long polling config updates
author Matt Johnston <matt@ucc.asn.au>
date Mon, 08 Jun 2015 22:29:46 +0800
parents 9b1d71310c83
children 26eee8591f61
line wrap: on
line diff
--- a/py/params.py	Wed May 27 23:46:06 2015 +0800
+++ b/py/params.py	Mon Jun 08 22:29:46 2015 +0800
@@ -3,9 +3,11 @@
 import json
 import signal
 import io
+import tempfile
 
 import config
 from utils import W,L,E,EX
+import utils
 
 _FIELD_DEFAULTS = {
     'fridge_setpoint': 16,
@@ -24,6 +26,7 @@
 
     def __init__(self):
         self.update(_FIELD_DEFAULTS)
+        self._epoch = None
 
     def __getattr__(self, k):
         return self[k]
@@ -45,6 +48,7 @@
             if k not in self:
                 raise self.Error("Unknown parameter %s=%s in file '%s'" % (str(k), str(u[k]), getattr(f, 'name', '???')))
         self.update(u)
+        self._epoch = utils.hexnonce()
 
         L("Loaded parameters")
         L(self.save_string())
@@ -60,19 +64,54 @@
                     W("Missing parameter file, using defaults. %s" % str(e))
                     return
 
-    def _do_save(self, f):
-        json.dump(self, f, sort_keys=True, indent=4)
-        f.write('\n')
-        f.flush()
+    def get_epoch(self):
+        return self._epoch
+
+    def receive(self, params, epoch):
+        """ updates parameters from the server. does some validation,
+        writes config file to disk.
+        Returns True on success, False failure 
+        """
+
+        if epoch != self._epoch:
+            return
+
+        def same_type(a, b):
+            ta = type(a)
+            tb = type(b)
+
+            if ta == int:
+                ta = float
+            if tb == int:
+                tb = float
+
+            return ta == tb
 
-    def save(self, f = None):
-        if f:
-            return self._do_save(f)
-        else:
-            with file(config.PARAMS_FILE, 'w') as f:
-                return self._do_save(f)
+        if self.keys() != new_params.keys():
+            diff = self.keys() ^ new_params.keys()
+            E("Mismatching params, %s" % str(diff))
+            return False
+
+        for k, v in new_params.items():
+            if not same_type(v, self[k]):
+                E("Bad type for %s" % k)
+                return False
+
+        dir = os.path.dirname(config.PARAMS_FILE)
+        try:
+            t = tempfile.NamedTemporaryFile(prefix='config',
+                dir = dir,
+                delete = False)
+
+            t.write(json.dumps(new_params, sort_keys=True, indent=4)+'\n')
+            name = t.name
+            t.close()
+
+            os.rename(name, config.PARAMS_FILE)
+            return True
+        except Exception as e:
+            E("Problem: %s" % e)
+            return False
 
     def save_string(self):
-        s = io.StringIO()
-        self.save(s)
-        return s.getvalue()
+        return json.dumps(self, sort_keys=True, indent=4)