[kupfer] core: Write configuration by rename into place
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer] core: Write configuration by rename into place
- Date: Tue, 22 Mar 2011 23:47:10 +0000 (UTC)
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]