[core] generic functions to create "writing" filepath and rename the file

* only try to remove the file on windows
* only except for specific exception
* use the same functions to create the statistics file
This commit is contained in:
Fabien Castan 2018-07-24 14:32:24 +02:00
parent c6531bcc7b
commit 9e06fd9661

View file

@ -5,6 +5,7 @@ import datetime
import json import json
import logging import logging
import os import os
import platform
import re import re
import shutil import shutil
import time import time
@ -20,6 +21,24 @@ from meshroom.core.attribute import attribute_factory, ListAttribute, GroupAttri
from meshroom.core.exception import UnknownNodeTypeError from meshroom.core.exception import UnknownNodeTypeError
def getWritingFilepath(filepath):
return filepath + '.writing.' + str(uuid.uuid4())
def renameWritingToFinalPath(writingFilepath, filepath):
if platform.system() == 'Windows':
# On Windows, attempting to remove a file that is in use causes an exception to be raised.
# So we may need multiple trials, if someone is reading it at the same time.
for i in range(20):
try:
os.remove(filepath)
# if remove is successful, we can stop the iterations
break
except WindowsError:
pass
os.rename(writingFilepath, filepath)
class Status(Enum): class Status(Enum):
""" """
""" """
@ -194,19 +213,10 @@ class NodeChunk(BaseObject):
folder = os.path.dirname(statusFilepath) folder = os.path.dirname(statusFilepath)
if not os.path.exists(folder): if not os.path.exists(folder):
os.makedirs(folder) os.makedirs(folder)
statusFilepathWriting = statusFilepath + '.writing.' + str(uuid.uuid4()) statusFilepathWriting = getWritingFilepath(statusFilepath)
with open(statusFilepathWriting, 'w') as jsonFile: with open(statusFilepathWriting, 'w') as jsonFile:
json.dump(data, jsonFile, indent=4) json.dump(data, jsonFile, indent=4)
for i in range(20): renameWritingToFinalPath(statusFilepathWriting, statusFilepath)
try:
os.remove(statusFilepath)
# if remove is successful, we can stop the iterations
break
except:
# On Windows, attempting to remove a file that is in use causes an exception to be raised.
# So we may need multiple trials
pass
shutil.move(statusFilepathWriting, statusFilepath)
def upgradeStatusTo(self, newStatus, execMode=None): def upgradeStatusTo(self, newStatus, execMode=None):
if newStatus.value <= self.status.status.value: if newStatus.value <= self.status.status.value:
@ -238,10 +248,10 @@ class NodeChunk(BaseObject):
folder = os.path.dirname(statisticsFilepath) folder = os.path.dirname(statisticsFilepath)
if not os.path.exists(folder): if not os.path.exists(folder):
os.makedirs(folder) os.makedirs(folder)
statisticsFilepathWriting = statisticsFilepath + '.writing.' + str(uuid.uuid4()) statisticsFilepathWriting = getWritingFilepath(statisticsFilepath)
with open(statisticsFilepathWriting, 'w') as jsonFile: with open(statisticsFilepathWriting, 'w') as jsonFile:
json.dump(data, jsonFile, indent=4) json.dump(data, jsonFile, indent=4)
shutil.move(statisticsFilepathWriting, statisticsFilepath) renameWritingToFinalPath(statisticsFilepathWriting, statisticsFilepath)
def isAlreadySubmitted(self): def isAlreadySubmitted(self):
return self.status.status in (Status.SUBMITTED, Status.RUNNING) return self.status.status in (Status.SUBMITTED, Status.RUNNING)