gjr80 / weewx-realtime_gauge-data

Near realtime support for updating of SteelSeries Weather Gauges by WeeWX
GNU General Public License v3.0
9 stars 5 forks source link

Write gauge data file atomically #10

Closed bakerkj closed 6 years ago

bakerkj commented 6 years ago

Currently this extension can write the gauge data file at the same time a webserver is reading the file. This can lead to the client getting an incomplete file. I'd suggest writing the file to a temporary file and then moving it atomically into place. Something like the following...

diff --git a/bin/user/rtgd.py b/bin/user/rtgd.py
index e7d3cc3..4860126 100644
--- a/bin/user/rtgd.py
+++ b/bin/user/rtgd.py
@@ -374,6 +374,7 @@ import errno
 import httplib
 import json
 import math
+import os
 import os.path
 import socket
 import syslog
@@ -678,6 +679,7 @@ class RealtimeGaugeDataThread(threading.Thread):
         self.rtgd_path_file = os.path.join(self.rtgd_path,
                                            rtgd_config_dict.get('rtgd_file_name',
                                                                 'gauge-data.txt'))
+        self.rtgd_tmp_path_file = self.rtgd_path_file + "~"

         # get the remote server URL if it exists, if it doesn't set it to None
         self.remote_server_url = rtgd_config_dict.get('remote_server_url', None)
@@ -1140,9 +1142,11 @@ class RealtimeGaugeDataThread(threading.Thread):
             if error.errno != errno.EEXIST:
                 raise
         # now write to file
-        with open(self.rtgd_path_file, 'w') as f:
+        with open(self.rtgd_tmp_path_file, 'w') as f:
             json.dump(data, f, separators=(',', ':'), sort_keys=True)

+        os.rename(self.rtgd_tmp_path_file, self.rtgd_path_file)
+
     def get_scroller_text(self):
         """Obtain the text string to be used in the scroller.
gjr80 commented 6 years ago

Good idea, weeWx does a similar thing with generated reports (introduced at v 2.6.0 refer cheetahgenerator.py lines 321-353) Will add something similar to the next release. Probably be a few days.

gjr80 commented 6 years ago

Ok, few days have turned into a few months. Will see if I can get this and #9 out in the next week or so.

gjr80 commented 6 years ago

Implemented at commit a0118498d6f171e9e0317ba6c9b4a4132df1ee08