[kupfer] core: Write configuration by rename into place



commit 2ffd6bed5409d52185126c8fa3f59ba3f2aea6d6
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Wed Mar 23 00:45:21 2011 +0100

    core: Write configuration by rename into place
    
    This is the standard way for atomic updates of files. We simply write
    to filename.<pid> and the rename (overwrite) that to filename.

 kupfer/core/learn.py    |    8 ++++++--
 kupfer/core/settings.py |    5 ++++-
 kupfer/core/sources.py  |    5 ++++-
 3 files changed, 14 insertions(+), 4 deletions(-)
---
diff --git a/kupfer/core/learn.py b/kupfer/core/learn.py
index 88f6e02..fe31139 100644
--- a/kupfer/core/learn.py
+++ b/kupfer/core/learn.py
@@ -1,4 +1,5 @@
 import cPickle as pickle
+import os
 
 from kupfer import config
 from kupfer import conspickle
@@ -59,9 +60,12 @@ class Learning (object):
 
 	@classmethod
 	def _pickle_register(self, reg, pickle_file):
-		with open(pickle_file, "wb") as output:
-			pretty.print_debug(__name__, "Saving to %s" % (pickle_file, ))
+		## Write to tmp then rename over for atomicity
+		tmp_pickle_file = "%s.%s" % (pickle_file, os.getpid())
+		pretty.print_debug(__name__, "Saving to %s" % (pickle_file, ))
+		with open(tmp_pickle_file, "wb") as output:
 			output.write(pickle.dumps(reg, pickle.HIGHEST_PROTOCOL))
+		os.rename(tmp_pickle_file, pickle_file)
 		return True
 
 _register = {}
diff --git a/kupfer/core/settings.py b/kupfer/core/settings.py
index 5eef2b8..a932447 100644
--- a/kupfer/core/settings.py
+++ b/kupfer/core/settings.py
@@ -162,8 +162,11 @@ class SettingsController (gobject.GObject, pretty.OutputMixin):
 
 		confmap = confmap_difference(self._config, default_confmap)
 		fill_parser(parser, confmap)
-		with open(config_path, "w") as out:
+		## Write to tmp then rename over for it to be atomic
+		temp_config_path = "%s.%s" % (config_path, os.getpid())
+		with open(temp_config_path, "w") as out:
 			parser.write(out)
+		os.rename(temp_config_path, config_path)
 
 	def get_config(self, section, key):
 		"""General interface, but section must exist"""
diff --git a/kupfer/core/sources.py b/kupfer/core/sources.py
index 91756a9..41d81c6 100644
--- a/kupfer/core/sources.py
+++ b/kupfer/core/sources.py
@@ -239,9 +239,12 @@ class SourceDataPickler (pretty.OutputMixin):
 			data = None
 		if data:
 			self.output_debug("Storing configuration for", source, "as", sname)
-			output = self.open(pickle_file, "wb")
+			## Write to temporary and rename into place
+			tmp_pickle_file = "%s.%s" % (pickle_file, os.getpid())
+			output = self.open(tmp_pickle_file, "wb")
 			output.write(data)
 			output.close()
+			os.rename(tmp_pickle_file, pickle_file)
 		return True
 
 class SourceController (pretty.OutputMixin):



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]