Я работаю над проектом на ненадежной системе, которая, как я предполагаю, может в любой момент провалиться. Что я хочу гарантировать, так это то, что если я запишу write_state, и машина потерпит неудачу в середине операции, read_state будет либо читать действительное состояние, либо вообще не будет состояния. Я реализовал что-то, что, я думаю, будет работать ниже - меня интересует критика этого или альтернативных решений, если кто-то знает об этом.
Моя идея:
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) < 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...')
например:.
write_state('test_log', {'x': 5})
print get_state('test_log')