Skip to content
Snippets Groups Projects
Commit b2df573e authored by Izzard, Robert Dr (Maths & Physics)'s avatar Izzard, Robert Dr (Maths & Physics)
Browse files

backport changes to use locked_close() etc.

parent e385b057
No related branches found
No related tags found
No related merge requests found
...@@ -93,7 +93,7 @@ class dataIO(): ...@@ -93,7 +93,7 @@ class dataIO():
object.grid_ensemble_results["metadata"] = {} object.grid_ensemble_results["metadata"] = {}
# add datestamp # add datestamp
object.grid_ensemble_results["metadata"]['save_population_time'] = self.now() object.grid_ensemble_results["metadata"]['save_population_time'] = self.now()
# add extra metadata # add extra metadata
object.add_system_metadata() object.add_system_metadata()
...@@ -252,7 +252,7 @@ class dataIO(): ...@@ -252,7 +252,7 @@ class dataIO():
# set the start position for new stars # set the start position for new stars
self.grid_options['start_at'] = newpop.grid_options['start_at'] self.grid_options['start_at'] = newpop.grid_options['start_at']
print("Loaded from snapshot at {file} : {nstars} stars, start at star {nstart}".format( print("Loaded from snapshot at {file} : {nstars} stars, start at star {nstart}".format(
file=file, file=file,
nstars=0,#self.grid_options[''], nstars=0,#self.grid_options[''],
...@@ -489,6 +489,25 @@ class dataIO(): ...@@ -489,6 +489,25 @@ class dataIO():
if self.HPC_job(): if self.HPC_job():
self.HPC_set_status(string) self.HPC_set_status(string)
def locked_close(self,
file,
lock):
"""
Partner function to locked_open()
Closes and unlocks the file
"""
print("locked_close:\nFile now = {}".format(file))
print("Lock now = {}".format(lock))
if file:
print("Close file {}".format(file))
file.close()
if lock:
print("Unlock {}".format(lock))
lock.unlock()
print("File now = {}".format(file))
print("Lock now = {}".format(lock))
def locked_open(self, def locked_open(self,
file, file,
mode="r", mode="r",
...@@ -504,11 +523,11 @@ class dataIO(): ...@@ -504,11 +523,11 @@ class dataIO():
We check whether the file exists, in which case just return We check whether the file exists, in which case just return
(None,None), and if we cannot get the lock we return (None,None), and if we cannot get the lock we return
(None,None). (None,None).
If the file does not exist, we keep trying to lock until it does. If the file does not exist, we keep trying to lock until it does.
To do the locking, we use flufl.lock which is NFS safe. To do the locking, we use flufl.lock which is NFS safe.
Args: Args:
lock_lifetime: (passed to flufl.lock.Lock()) default 60 seconds. lock_lifetime: (passed to flufl.lock.Lock()) default 60 seconds.
It should take less than this time to write the file. It should take less than this time to write the file.
...@@ -518,57 +537,70 @@ class dataIO(): ...@@ -518,57 +537,70 @@ class dataIO():
Returns: Returns:
(file_object, lock_object) tuple. (file_object, lock_object) tuple.
If the file was not opened, returns (None,None). If the file was not opened, returns (None,None).
""" """
# set the lockfile path: this should be the same # set the lockfile path: this should be the same
# for all processes, so it's just the original file # for all processes, so it's just the original file
# plus the lock_suffix # plus the lock_suffix
lockfile = file + lock_suffix lockfile = file + lock_suffix
print("lockfile={}".format(lockfile))
while True: while True:
# if the file exists, just return # if the file exists, just return
if os.path.isfile(lockfile): if os.path.isfile(file):
print("file {} already exists".format(file))
return (None,None) return (None,None)
# make the lock object by opening the lockfile # make the lock object by opening the lockfile
lock = flufl.lock.Lock(lockfile, lock = flufl.lock.Lock(lockfile,
default_timeout=lock_timeout) default_timeout=lock_timeout)
print("post-lock: {}",format(lock))
if lock: if lock:
# we have the lockfile, so set the lifetime and try to lock it # we have the lockfile, so set the lifetime and try to lock it
lock.lifetime = datetime.timedelta(seconds=lock_lifetime) lock.lifetime = datetime.timedelta(seconds=lock_lifetime)
try: try:
print("try to lock",format(lock))
lock.lock() lock.lock()
print("locked {}".format(lock))
except: except:
pass pass
# if we acquired the lock, try to open the file # if we acquired the lock, try to open the file
if lock.is_locked: if lock.is_locked:
print("is locked {}",lock)
# check it hasn't been opened in the meantime # check it hasn't been opened in the meantime
if os.path.isfile(file): if os.path.isfile(file):
print("in the meantime, {} has been opened".format(file))
lock.unlock() lock.unlock()
print("unlocked {} : return None,None".format(lock))
return (None,None) return (None,None)
# All is apparently ok: file is locked and does not # All is apparently ok: file is locked and does not
# exist so open the file # exist so open the file
try: try:
print("Try to open {}",file)
f = open(file, f = open(file,
mode=mode, mode=mode,
encoding=encoding, encoding=encoding,
**kwargs) **kwargs)
print("Return locked file {}, {}".format(f,lock))
return (f,lock) return (f,lock)
# error on open should be fatal # error on open should be fatal
except Exception as e: except Exception as e:
print("Error in locked_open() : {}",e) print("Error in locked_open() : {}",e)
if fatal_open_errors: if fatal_open_errors:
print("fatal EXIT")
self.exit(1) self.exit(1)
else: else:
print("unlock {}".format(lock))
lock.unlock() lock.unlock()
print("unlocked {} return None,None".format(lock))
return (None,None) return (None,None)
# failed to lock this time, keep trying # failed to lock this time, keep trying
# (we shouldn't lock up the CPU because the timeout is non-zero) # (we shouldn't lock up the CPU because the timeout is non-zero)
continue continue
...@@ -613,21 +613,20 @@ class Population(analytics, ...@@ -613,21 +613,20 @@ class Population(analytics,
# open locked settings file, then output if we get the lock # open locked settings file, then output if we get the lock
(f,lock) = self.locked_open(settings_fullname, (f,lock) = self.locked_open(settings_fullname,
mode="w") mode="w")
if lock: if lock and f:
self.verbose_print( self.verbose_print(
"Writing settings to {}".format(settings_fullname), "Writing settings to {}".format(settings_fullname),
self.grid_options["verbosity"], self.grid_options["verbosity"],
1, 1,
) )
if f: json.dump(
json.dump( all_info_cleaned,
all_info_cleaned, f,
f, indent=indent,
indent=indent, default=binaryc_json_serializer,
default=binaryc_json_serializer, ensure_ascii=ensure_ascii
ensure_ascii=ensure_ascii )
) self.locked_close(f,lock)
lock.unlock()
return settings_fullname return settings_fullname
else: else:
msg = "Exporting all info without passing a value for `outfile` requires custom_options['data_dir'] to be present. That is not the cause. Either set the `data_dir` or pass a value for `outfile` " msg = "Exporting all info without passing a value for `outfile` requires custom_options['data_dir'] to be present. That is not the cause. Either set the `data_dir` or pass a value for `outfile` "
......
...@@ -385,7 +385,7 @@ class gridcode(): ...@@ -385,7 +385,7 @@ class gridcode():
) )
# Add condition failed action: # Add condition failed action:
if self.grid_options["verbosity"] >= 3: if self.grid_options["verbosity"] >= 4:
self._add_code( self._add_code(
'print("Grid generator: Condition for {name} not met!")'.format( 'print("Grid generator: Condition for {name} not met!")'.format(
name=grid_variable["name"] name=grid_variable["name"]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment