Re-synchronised capture IO

This commit is contained in:
Joel Collins 2020-07-03 15:05:53 +01:00
parent 489b81f34b
commit 44cbc87416

View file

@ -10,9 +10,6 @@ from PIL import Image
import dateutil.parser import dateutil.parser
import atexit import atexit
from gevent.fileobject import FileObjectThread
import gevent
from collections import OrderedDict from collections import OrderedDict
from openflexure_microscope.camera import piexif from openflexure_microscope.camera import piexif
@ -129,10 +126,6 @@ class CaptureObject(object):
"""Create a new StreamObject, to manage capture data.""" """Create a new StreamObject, to manage capture data."""
# Stream for buffering capture data # Stream for buffering capture data
self.stream = io.BytesIO() self.stream = io.BytesIO()
# Event to notify when the stream has finished writing to disk
self.file_ready = gevent.event.Event()
# Access lock for the disk file
self.lock = gevent.lock.BoundedSemaphore()
# Store a nice ID # Store a nice ID
self.id = uuid.uuid4() #: str: Unique capture ID self.id = uuid.uuid4() #: str: Unique capture ID
@ -160,19 +153,12 @@ class CaptureObject(object):
def write(self, s): def write(self, s):
self.stream.write(s) self.stream.write(s)
def _stream_to_file(self):
with self.lock:
logging.info(f"Writing to disk {self.file}")
with FileObjectThread(open(self.file, "wb"), 'wb') as outfile:
outfile.write(self.stream.getbuffer())
self.stream.close()
self.file_ready.set()
logging.info(f"Finished writing to disk {self.file}")
def flush(self): def flush(self):
logging.debug(f"Flushing {self.file}") logging.info(f"Writing to disk {self.file}")
gevent.spawn(self._stream_to_file) with open(self.file, "wb") as outfile:
logging.debug(f"Returning flushing {self.file}") outfile.write(self.stream.getbuffer())
self.stream.close()
logging.info(f"Finished writing to disk {self.file}")
def open(self, mode): def open(self, mode):
return open(self.file, mode) return open(self.file, mode)
@ -275,20 +261,18 @@ class CaptureObject(object):
global EXIF_FORMATS global EXIF_FORMATS
if self.format.upper() in EXIF_FORMATS and self.exists: if self.format.upper() in EXIF_FORMATS and self.exists:
self.file_ready.wait() logging.debug("Writing exif data to capture file")
with self.lock: # Extract current Exif data
logging.debug("Writing exif data to capture file") exif_dict = piexif.load(self.file)
# Extract current Exif data # Serialize metadata
exif_dict = piexif.load(self.file) metadata_string = json.dumps(self.metadata, cls=JSONEncoder)
# Serialize metadata logging.debug(f"Saving metadata string to file: {metadata_string}")
metadata_string = json.dumps(self.metadata, cls=JSONEncoder) # Insert metadata into exif_dict
logging.debug(f"Saving metadata string to file: {metadata_string}") exif_dict["Exif"][piexif.ExifIFD.UserComment] = metadata_string.encode()
# Insert metadata into exif_dict # Convert new exif dict to exif bytes
exif_dict["Exif"][piexif.ExifIFD.UserComment] = metadata_string.encode() exif_bytes = piexif.dump(exif_dict)
# Convert new exif dict to exif bytes # Insert exif into file
exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, self.file)
# Insert exif into file
piexif.insert(exif_bytes, self.file)
logging.info(f"Finished saving metadata to {self.file}") logging.info(f"Finished saving metadata to {self.file}")
@property @property