Skip to content
Snippets Groups Projects
Commit 7ec17a5e authored by Steffen Hauf's avatar Steffen Hauf
Browse files

Add copying, make handling async

parent e4541c92
No related branches found
No related tags found
1 merge request!44add a web service to launch calibration from MDC
...@@ -123,6 +123,13 @@ async def update_job_db(config): ...@@ -123,6 +123,13 @@ async def update_job_db(config):
await asyncio.sleep(int(config['web-service']['job-update-interval'])) await asyncio.sleep(int(config['web-service']['job-update-interval']))
async def copy_untouched_files(file_list):
for f in file_list:
of = f.replace("raw", "proc").replace("RAW", "CORR")
cmd = ["rsync", "-av", f, of]
await asyncio.subprocess.create_subprocess_shell(" ".join(cmd))
logging.info("Copying {} to {}".format(f, of))
async def run_cmd(conn, cmd, mode, proposal, run, rpath): async def run_cmd(conn, cmd, mode, proposal, run, rpath):
""" Run a correction command """ Run a correction command
...@@ -229,81 +236,88 @@ async def server_runner(config, mode): ...@@ -229,81 +236,88 @@ async def server_runner(config, mode):
socket.send(Errors.UNKNOWN_ACTION.format(action).encode()) socket.send(Errors.UNKNOWN_ACTION.format(action).encode())
continue continue
if action == 'correct': async def do_action():
sase, instrument, cycle, proposal, runnr = payload if action == 'correct':
specific_conf_file = "{}/{}/{}.yaml".format(config['config-repo']['local-path'], cycle, proposal) sase, instrument, cycle, proposal, runnr = payload
if os.path.exists(specific_conf_file): specific_conf_file = "{}/{}/{}.yaml".format(config['config-repo']['local-path'], cycle, proposal)
with open(specific_conf_file, "r") as f: if os.path.exists(specific_conf_file):
pconf = yaml.load(f.read()) with open(specific_conf_file, "r") as f:
else: pconf = yaml.load(f.read())
print("Using default file, as {} does not exist".format(specific_conf_file)) else:
default_file = "{}/default.yaml".format(config['config-repo']['local-path']) print("Using default file, as {} does not exist".format(specific_conf_file))
with open(default_file, "r") as f: default_file = "{}/default.yaml".format(config['config-repo']['local-path'])
pconf = yaml.load(f.read()) with open(default_file, "r") as f:
pconf = yaml.load(f.read())
in_folder = config['correct']['in-folder'].format(instrument=instrument, cycle=cycle, proposal=proposal)
out_folder = config['correct']['out-folder'].format(instrument=instrument, cycle=cycle, proposal=proposal) in_folder = config['correct']['in-folder'].format(instrument=instrument, cycle=cycle, proposal=proposal)
detectors = {} out_folder = config['correct']['out-folder'].format(instrument=instrument, cycle=cycle, proposal=proposal)
rpath = "{}/r{:04d}/".format(in_folder, int(runnr)) detectors = {}
async def wait_on_transfer(): rpath = "{}/r{:04d}/".format(in_folder, int(runnr))
rstr = None async def wait_on_transfer():
ret = None rstr = None
max_tries = 60 # 600s ret = None
tries = 0 max_tries = 60 # 600s
while not os.path.exists(rpath): tries = 0
await asyncio.sleep(10) while not os.path.exists(rpath):
await asyncio.sleep(1) await asyncio.sleep(10)
while rstr is None or 'status="online"' in rstr or ret.returncode != 0: # await asyncio.sleep(1)
print(" ".join(["getfattr", "-n", "user.status", rpath])) while rstr is None or 'status="online"' in rstr or ret.returncode != 0:
ret = subprocess.run(["getfattr", "-n", "user.status", rpath], stdout=subprocess.PIPE) print(" ".join(["getfattr", "-n", "user.status", rpath]))
rstr = ret.stdout.decode() ret = subprocess.run(["getfattr", "-n", "user.status", rpath], stdout=subprocess.PIPE)
await asyncio.sleep(10) rstr = ret.stdout.decode()
if tries > max_tries: await asyncio.sleep(10)
return False if tries > max_tries:
tries += 1 return False
tries += 1
return ret.returncode == 0
return ret.returncode == 0
msg = "Queued proposal {}, run {} for offline calibration".format(proposal, runnr)
socket.send(msg.encode()) msg = "Queued proposal {}, run {} for offline calibration".format(proposal, runnr)
socket.send(msg.encode())
transfer_complete = await wait_on_transfer()
if not transfer_complete: transfer_complete = await wait_on_transfer()
logging.error(Errors.TRANSFER_EVAL_FAILED.format(proposal, runnr)) if not transfer_complete:
return Errors.TRANSFER_EVAL_FAILED.format(proposal, runnr) logging.error(Errors.TRANSFER_EVAL_FAILED.format(proposal, runnr))
return Errors.TRANSFER_EVAL_FAILED.format(proposal, runnr)
for detector, dconfig in pconf[instrument].items():
# check if we find files according to mapping in raw run folder corr_file_list = set()
fl = glob.glob("{}/RAW-*{}*.h5".format(rpath, dconfig["inset"])) copy_file_list = set(glob.glob("{}/*.h5".format(rpath)))
if len(fl): for detector, dconfig in pconf[instrument].items():
thisconf = copy.copy(dconfig) # check if we find files according to mapping in raw run folder
thisconf["in-folder"] = in_folder fl = glob.glob("{}/RAW-*{}*.h5".format(rpath, dconfig["inset"]))
thisconf["out-folder"] = out_folder if len(fl):
thisconf["run"] = runnr corr_file_list = corr_file_list.union(set(fl))
del thisconf["inset"] # don't need this for xfel-calibrate thisconf = copy.copy(dconfig)
detectors[detector] = thisconf thisconf["in-folder"] = in_folder
thisconf["out-folder"] = out_folder
if len(detectors) == 0: thisconf["run"] = runnr
logging.warn(Errors.NOTHING_TO_DO.format(rpath)) del thisconf["inset"] # don't need this for xfel-calibrate
socket.send(Errors.NOTHING_TO_DO.format(rpath).encode()) detectors[detector] = thisconf
continue
status = [] copy_file_list = copy_file_list.difference(corr_file_list)
for detector, dconfig in detectors.items(): asyncio.ensure_future(copy_untouched_files(copy_file_list))
cmd = ["python", "-m", "xfel_calibrate.calibrate", detector, "CORRECT"]
for key, value in dconfig.items(): if len(detectors) == 0:
if not isinstance(value, bool): logging.warn(Errors.NOTHING_TO_DO.format(rpath))
cmd += ["--{}".format(key), str(value)] socket.send(Errors.NOTHING_TO_DO.format(rpath).encode())
else: return
cmd += ["--{}".format(key)] status = []
ret = await run_cmd(job_db, cmd, mode, proposal, runnr, dconfig["in-folder"]) for detector, dconfig in detectors.items():
status.append(ret) cmd = ["python", "-m", "xfel_calibrate.calibrate", detector, "CORRECT"]
#socket.send(("\n".join(status)).encode()) for key, value in dconfig.items():
if not isinstance(value, bool):
if action == 'upload-yaml': cmd += ["--{}".format(key), str(value)]
sase, instrument, cycle, proposal, this_yaml = payload else:
this_yaml = urllib.parse.unquote_plus(this_yaml) cmd += ["--{}".format(key)]
await upload_config(socket, config['config-repo'], this_yaml, instrument, cycle, proposal) ret = await run_cmd(job_db, cmd, mode, proposal, runnr, dconfig["in-folder"])
status.append(ret)
#socket.send(("\n".join(status)).encode())
if action == 'upload-yaml':
sase, instrument, cycle, proposal, this_yaml = payload
this_yaml = urllib.parse.unquote_plus(this_yaml)
await upload_config(socket, config['config-repo'], this_yaml, instrument, cycle, proposal)
asyncio.ensure_future(do_action())
parser = argparse.ArgumentParser(description='Start the calibration webservice') parser = argparse.ArgumentParser(description='Start the calibration webservice')
parser.add_argument('--config-file', type=str, default='./webservice.yaml') parser.add_argument('--config-file', type=str, default='./webservice.yaml')
......
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