diff --git a/pycromanager/_version.py b/pycromanager/_version.py index 7feff9bf..b6675a0a 100644 --- a/pycromanager/_version.py +++ b/pycromanager/_version.py @@ -1,2 +1,2 @@ -version_info = (0, 29, 0) +version_info = (0, 29, 1) __version__ = ".".join(map(str, version_info)) diff --git a/pycromanager/acquisition/java_backend_acquisitions.py b/pycromanager/acquisition/java_backend_acquisitions.py index 0c19ab12..cab4faaa 100644 --- a/pycromanager/acquisition/java_backend_acquisitions.py +++ b/pycromanager/acquisition/java_backend_acquisitions.py @@ -209,6 +209,7 @@ def _notification_handler_fn(acquisition, notification_push_port, connected_even finally: monitor_socket.close() + class JavaBackendAcquisition(Acquisition, metaclass=NumpyDocstringInheritanceMeta): """ Pycro-Manager acquisition that uses a Java runtime backend via a ZeroMQ communication layer. @@ -366,6 +367,7 @@ def await_completion(self): # for backwards compatiblitiy with older versions of Pycromanager java before this added self._acq_notification_recieving_thread.join() self._remote_notification_handler.notification_handling_complete() + self._remote_notification_handler = None # this prevents a circular reference self._acq_notification_dispatcher_thread.join() self._acq = None diff --git a/pycromanager/zmq_bridge/_bridge.py b/pycromanager/zmq_bridge/_bridge.py index 7d7cd9b3..d8d3d858 100644 --- a/pycromanager/zmq_bridge/_bridge.py +++ b/pycromanager/zmq_bridge/_bridge.py @@ -246,35 +246,14 @@ def create_or_get_existing_bridge(port: int=DEFAULT_PORT, convert_camel_case: bo if debug: print("DEBUG: creating new beidge for port {} thread {}".format( port, threading.current_thread().name)) - return _Bridge(port, convert_camel_case, debug, ip_address, timeout, iterate) - - - # def __new__(cls, port: int=DEFAULT_PORT, timeout: int=DEFAULT_TIMEOUT, convert_camel_case: bool=True, - # debug: bool=False, *args, **kwargs): - # """ - # Only one instance of Bridge per a thread/port combo - # """ - # # synchronize this method so multiple threads don't try to create a bridge at the same time - # with _Bridge._bridge_creation_lock: - # thread_id = threading.current_thread().ident - # port_thread_id = (port, thread_id) - # - # # return the existing cached bridge if it exists, otherwise make a new one - # if port_thread_id in _Bridge._cached_bridges_by_port_and_thread.keys(): - # bridge = _Bridge._cached_bridges_by_port_and_thread[port_thread_id]() - # if bridge is None: - # raise Exception("Bridge for port {} and thread {} has been " - # "closed but not removed".format(port, threading.current_thread().name)) - # if debug: - # print("DEBUG: returning cached bridge for port {} thread {}".format( - # port, threading.current_thread().name)) - # return bridge - # else: - # if debug: - # print("DEBUG: creating new beidge for port {} thread {}".format( - # port, threading.current_thread().name)) - # return super(_Bridge, cls).__new__(cls) - + b = _Bridge(port, convert_camel_case, debug, ip_address, timeout, iterate) + # store weak refs so that the existence of thread/port bridge caching doesn't prevent + # the garbage collection of unused bridge objects + _Bridge._cached_bridges_by_port_and_thread[port_thread_id] = weakref.ref(b) + print('cached bridges') + for key, beidge in _Bridge._cached_bridges_by_port_and_thread.items(): + print(key, beidge()) + return b def __init__( self, port: int=DEFAULT_PORT, convert_camel_case: bool=True, @@ -297,14 +276,7 @@ def __init__( """ thread_id = threading.current_thread().ident port_thread_id = (port, thread_id) - # if port_thread_id in _Bridge._cached_bridges_by_port_and_thread.keys(): - # return # already initialized self._port_thread_id = port_thread_id - # store weak refs so that the existence of thread/port bridge caching doesn't prevent - # the garbage collection of unused bridge objects - self._weak_self_ref = weakref.ref(self) - _Bridge._cached_bridges_by_port_and_thread[port_thread_id] = self._weak_self_ref - self._ip_address = ip_address self.port = port self._convert_camel_case = convert_camel_case @@ -571,9 +543,9 @@ def __init__(self, serialized_object, bridge: _Bridge): self._iterate = bridge._iterate self._closed = False - # In case there's an exception rather than normal garbage collection, - # this makes sure cleanup occurs properly - # Need to use a wr to ensure that reference to close doesnt cause memeory leak + # # In case there's an exception rather than normal garbage collection, + # # this makes sure cleanup occurs properly + # # Need to use a wr to ensure that reference to close doesnt cause memeory leak wr = weakref.ref(self._close) def cleanup(): if wr() is not None: