def get_measurement(measurement_id):
# XXX this query is SUPER slow
m = RE_MSM_ID.match(measurement_id)
if not m:
raise BadRequest("Invalid measurement_id")
msm_no = int(m.group(1))
q = current_app.db_session.query(
Measurement.report_no.label('report_no'),
Measurement.frame_off.label('frame_off'),
Measurement.frame_size.label('frame_size'),
Measurement.intra_off.label('intra_off'),
Measurement.intra_size.label('intra_size'),
Report.report_no.label('r_report_no'),
Report.autoclaved_no.label('r_autoclaved_no'),
Autoclaved.filename.label('a_filename'),
Autoclaved.autoclaved_no.label('a_autoclaved_no'),
).filter(Measurement.msm_no == msm_no)\
.join(Report, Report.report_no == Measurement.report_no)\
.join(Autoclaved, Autoclaved.autoclaved_no == Report.autoclaved_no)
try:
msmt = q.one()
except exc.MultipleResultsFound:
current_app.logger.warning("Duplicate rows for measurement_id: %s" % measurement_id)
msmt = q.first()
except exc.NoResultFound:
# XXX we should actually return a 404 here
raise BadRequest("No measurement found")
# Usual size of LZ4 frames is 256kb of decompressed text.
# Largest size of LZ4 frame was ~55Mb compressed and ~56Mb decompressed. :-/
range_header = "bytes={}-{}".format(msmt.frame_off, msmt.frame_off + msmt.frame_size - 1)
r = requests.get(urljoin(current_app.config['AUTOCLAVED_BASE_URL'], msmt.a_filename),
headers={"Range": range_header})
r.raise_for_status()
blob = r.content
if len(blob) != msmt.frame_size:
raise RuntimeError('Failed to fetch LZ4 frame', len(blob), msmt.frame_size)
blob = lz4framed.decompress(blob)[msmt.intra_off:msmt.intra_off+msmt.intra_size]
if len(blob) != msmt.intra_size or blob[:1] != b'{' or blob[-1:] != b'}':
raise RuntimeError('Failed to decompress LZ4 frame to measurement.json', len(blob), msmt.intra_size, blob[:1], blob[-1:])
# There is no replacement of `measurement_id` with `msm_no` or anything
# else to keep sanity. Maybe it'll happen as part of orchestration update.
# Also, blob is not decoded intentionally to save CPU
return current_app.response_class(
blob,
mimetype=current_app.config['JSONIFY_MIMETYPE']
)
评论列表
文章目录