micro-manager / pycro-manager

Python control of micro-manager for customized data acquisition
https://pycro-manager.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
165 stars 52 forks source link

Execution Blocked if Socket times out or unavailable. (Core) #786

Closed samhitech closed 4 months ago

samhitech commented 5 months ago

Hi, I'm uncertain whether this was done on purpose or if it's a bug. If a timeout occurs or if micromanager isn't running, the entire code freezes and the exception cannot be handled.

Code for reproduction

from pycromanager import Core

try:
    core = Core()
except Exception as e:
    print(e)

# do anything afterward
print('here')

Expected outcome

printed 'error message' printed 'here'

where further execution is not blocked

Actual outcome

Exception in thread BridgeSocketThread_port4827: Traceback (most recent call last): File "C:\Users\Nour\AppData\Local\Programs\Python\Python39\lib\threading.py", line 980, in _bootstrap_inner self.run() File "C:\Users\Nour\AppData\Local\Programs\Python\Python39\lib\threading.py", line 917, in run self._target(*self._args, *self._kwargs) File "C:\Users\Nour\AppData\Local\Programs\Python\Python39\lib\site-packages\pyjavaz\bridge.py", line 341, in _run_socket_thread raise Exception(f"Socket timed out after {self._timeout} milliseconds") Exception: Socket timed out after 1000 milliseconds (Here execution freezes)*

henrypinkard commented 5 months ago

Should be fixed in https://github.com/micro-manager/pycro-manager/pull/787

samhitech commented 4 months ago

Thanks, after upgrading to the latest release, that issue was fixed for this Exception. Yet, when facing any other Exceptions, it still freezes, for example below when the index is out of range:

>>> from pycromanager import Core
>>> core = Core()
>>> props = core.get_device_property_names('Z')
>>> props
<pyjavaz.bridge.mmcorej_StrVector object at 0x0000023EFF2962E0>
>>> props.get(3) 
'Position'
>>> props.get(6) 
Exception in thread BridgeSocketThread_port4827:
Traceback (most recent call last):
  File "C:\Users\Nour\AppData\Local\Programs\Python\Python39\lib\threading.py", line 980, in _bootstrap_inner
    self.run()
  File "C:\Users\Nour\AppData\Local\Programs\Python\Python39\lib\threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Nour\AppData\Local\Programs\Python\Python39\lib\site-packages\pyjavaz\bridge.py", line 367, in _run_socket_thread
    response = socket.receive()
  File "C:\Users\Nour\AppData\Local\Programs\Python\Python39\lib\site-packages\pyjavaz\bridge.py", line 192, in receive
    self._check_exception(message)
  File "C:\Users\Nour\AppData\Local\Programs\Python\Python39\lib\site-packages\pyjavaz\bridge.py", line 197, in _check_exception
    raise Exception(response["value"])
Exception: java.lang.IndexOutOfBoundsException: vector index out of range
mmcorej.MMCoreJJNI.StrVector_get(Native Method)
mmcorej.StrVector.get(StrVector.java:113)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.micromanager.pyjavaz.ZMQServer.runMethod(ZMQServer.java:431)
org.micromanager.pyjavaz.ZMQServer.parseAndExecuteCommand(ZMQServer.java:511)
org.micromanager.pyjavaz.ZMQServer.lambda$initialize$2(ZMQServer.java:121)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)

Here frozen

Thanks!

henrypinkard commented 4 months ago

I think now fixed https://github.com/micro-manager/pycro-manager/pull/788