Removed async metadata. Added metadata cache.

This commit is contained in:
Joel Collins 2020-07-01 15:35:21 +01:00
parent 0101a5b91e
commit 1cba4205a6

View file

@ -6,6 +6,7 @@ import logging
import pkg_resources import pkg_resources
import uuid import uuid
from typing import Tuple from typing import Tuple
from expiringdict import ExpiringDict
import gevent import gevent
@ -61,6 +62,10 @@ class Microscope:
# Apply settings loaded from file # Apply settings loaded from file
self.update_settings(self.settings_file.load()) self.update_settings(self.settings_file.load())
# Data cache
self.configuration_cache = ExpiringDict(max_len=100, max_age_seconds=3600)
self.metadata_cache = ExpiringDict(max_len=100, max_age_seconds=3600)
def __enter__(self): def __enter__(self):
"""Create microscope on context enter.""" """Create microscope on context enter."""
return self return self
@ -252,8 +257,7 @@ class Microscope:
# Save config to file # Save config to file
self.settings_file.save(current_config, backup=True) self.settings_file.save(current_config, backup=True)
@property def force_get_configuration(self):
def configuration(self):
with self.lock: with self.lock:
initial_configuration = self.configuration_file.load() initial_configuration = self.configuration_file.load()
@ -277,17 +281,28 @@ class Microscope:
initial_configuration.update(current_configuration) initial_configuration.update(current_configuration)
return initial_configuration return initial_configuration
def get_configuration(self, cache_key=None):
if cache_key:
cached_config = self.configuration_cache.get(cache_key, None)
if cached_config:
return cached_config
else:
full_config = self.force_get_configuration()
self.configuration_cache[cache_key] = full_config
return full_config
return self.force_get_configuration()
@property @property
def metadata(self): def configuration(self):
return self.get_configuration()
def force_get_metadata(self):
""" """
Microscope system metadata, to be applied to basically all captures Microscope system metadata, to be applied to basically all captures
""" """
with Timer("Reading settings:"): settings = self.read_settings(full=False)
settings = self.read_settings(full=False) state = self.state
with Timer("Reading state:"): configuration = self.configuration
state = self.state
with Timer("Reading configuration:"):
configuration = self.configuration
system_metadata = { system_metadata = {
"id": self.id, "id": self.id,
"settings": settings, "settings": settings,
@ -297,17 +312,23 @@ class Microscope:
return system_metadata return system_metadata
def add_metadata_to_capture(self, output, metadata, annotations, tags): def get_metadata(self, cache_key=None):
logging.debug(f"Waiting for {output.file}") logging.debug(f"Looking for cache key {cache_key}")
# Wait for the file to be written to disk if cache_key:
with Timer("Waiting for file:"): cached_metadata = self.metadata_cache.get(cache_key, None)
output.file_ready.wait() if cached_metadata:
logging.debug(f"Reusing cached microscope metadata: {cache_key}")
return cached_metadata
else:
full_metadata = self.force_get_metadata()
self.metadata_cache[cache_key] = full_metadata
return full_metadata
logging.debug("Generating full microscope metadata")
return self.force_get_metadata()
with Timer("Building metadata"): @property
full_metadata = {"instrument": self.metadata, **metadata} def metadata(self):
with Timer("Writing metadata to file"): return self.get_metadata()
output.put_and_save(tags, annotations, full_metadata)
logging.info(f"Finished injecting EXIF data into {output.file}")
def capture( def capture(
self, self,
@ -321,6 +342,7 @@ class Microscope:
annotations: dict = None, annotations: dict = None,
tags: list = None, tags: list = None,
metadata: dict = None, metadata: dict = None,
cache_key: str = None
): ):
logging.debug(f"Microscope capturing to {filename}") logging.debug(f"Microscope capturing to {filename}")
if not annotations: if not annotations:
@ -337,7 +359,7 @@ class Microscope:
) )
# Capture to output object # Capture to output object
logging.info("Starting microscope capture...") logging.info(f"Starting microscope capture {filename}")
self.camera.capture( self.camera.capture(
output, output,
use_video_port=use_video_port, use_video_port=use_video_port,
@ -347,10 +369,13 @@ class Microscope:
) )
# Gether metadata from hardware in a greenlet # Gether metadata from hardware in a greenlet
#gevent.get_hub().threadpool.spawn(self.add_metadata_to_capture, output, metadata, annotations, tags) logging.debug(f"Waiting for {output.file}")
gevent.spawn(self.add_metadata_to_capture, output, metadata, annotations, tags) # Wait for the file to be written to disk
#self.add_metadata_to_capture(output, metadata, annotations, tags) output.file_ready.wait()
full_metadata = {"instrument": self.get_metadata(cache_key), **metadata}
output.put_and_save(tags, annotations, full_metadata)
logging.debug(f"Finished adding EXIF data to {output.file}")
logging.info(f"Finished capture to {output.file}") logging.debug(f"Finished capture to {output.file}")
return output return output