title: Atomic state storage in Python?
body: <p>I'm working on a project on an unreliable system which I'm assuming can fail at any point. What I want to guarantee is that if I write_state and the machine fails mid-operation, a read_state will either read a valid state or no state at all. I've implemented something which I think will work below -- I'm interested in criticism of that or alternative solutions if anyone knows of one.</p>
  
  <p>My idea:</p>
  
  <pre><code>import hashlib, cPickle, os
  
  def write_state(logname, state):
      state_string = cPickle.dumps(state, cPickle.HIGHEST_PROTOCOL)
      state_string += hashlib.sha224(state_string).hexdigest()
  
      handle = open('%s.1' % logname, 'wb')
      handle.write(state_string)
      handle.close()
  
      handle = open('%s.2' % logname, 'wb')
      handle.write(state_string)
      handle.close()
  
  def get_state(logname):
      def read_file(name):
          try:
              f = open(name,'rb')
              data = f.read()
              f.close()
              return data
          except IOError:
              return ''
      def parse(data):
          if len(data) &lt; 56:
              return (None, '', False)
          hash = data[-56:]
          data = data[:-56]
          valid = hashlib.sha224(data).hexdigest() == hash
          try:
              parsed = cPickle.loads(data)
          except cPickle.UnpicklingError:
              parsed = None
          return (parsed, valid)
  
      data1,valid1 = parse(read_file('%s.1'%logname))
      data2,valid2 = parse(read_file('%s.2'%logname))
  
      if valid1 and valid2:
          return data1
      elif valid1 and not valid2:
          return data1
      elif valid2 and not valid1:
          return data2
      elif not valid1 and not valid2:
          raise Exception('Theoretically, this never happens...')
  </code></pre>
  
  <p>e.g.:</p>
  
  <pre><code>write_state('test_log', {'x': 5})
  print get_state('test_log')
  </code></pre>