I need to do a series of operations involving binary files (you can not use BD), and I need to ensure that they finish successfully even in the middle of the operation. To do this, I see no way out but to implement a journaling system manually. I started to write a code, but I'm not sure if it's correct (ie if there are no cases where a failure in the middle of the task can put it in an inconsistent state - including failure in the journal's own ).
Is there anything ready in this regard? And if it does not exist, is there a problem in my attempt to resolve it?
def nova_tarefa(args):
refazer_journal() # Refaz o que ficou inacabado da última vez (se houver)
with open('args.json', 'w') as f:
json.dump(args, f) # Prepara as novas tarefas
with open('journal.txt', 'w') as f:
f.write('comecar\n') # Coloca as novas tarefas no journal
refazer_journal() # Faz as novas tarefas
def refazer_journal():
try:
with open('journal.txt', 'r') as f:
passos = [x.strip() for x in f.readlines() if x.strip()]
except:
if not os.path.exists('journal.txt'):
passos = []
else:
raise
if not passos: # Se não há nada inacabado, termina
return
with open('args.json', 'r') as f:
args = json.load(f)
# Realiza as tarefas que ainda não foram marcadas como concluídas
for indice,tarefa in enumerate(args['tarefas']):
if len(passos) <= indice+1:
realizar_tarefa_indepotente(tarefa)
with open('journal.txt', 'a') as f:
f.write('\ntarefa concluida\n')
with open('journal.txt', 'w') as f:
pass # Tudo foi feito com sucesso: esvazia o journal
(Note: what is written in the journal - comecar
, tarefa concluida
- is not important, if only one letter that is written on the line already considers that the step was well -suced)
Test code (with me always worked - including editing journal.txt
to introduce a series of errors):
def realizar_tarefa_indepotente(tarefa):
if 'falhar' in tarefa:
raise Exception('Tarefa falhou!')
print 'Realizando tarefa: ' + tarefa['nome']
tarefa_ok = {'tarefas':[{'nome':'foo'}, {'nome':'bar'}, {'nome':'baz'}]}
falha_3 = {'tarefas':[{'nome':'foo'}, {'nome':'bar'}, {'nome':'baz','falhar':True}]}
falha_2 = {'tarefas':[{'nome':'foo'}, {'nome':'bar','falhar':True}, {'nome':'baz'}]}
falha_1 = {'tarefas':[{'nome':'foo','falhar':True}, {'nome':'bar'}, {'nome':'baz'}]}
falha_1_3 = {'tarefas':[{'nome':'foo','falhar':True}, {'nome':'bar'}, {'nome':'baz','falhar':True}]}