Closed dieris closed 6 years ago
I'm stymied as to why the X6 is getting an h5 file descriptor... which branch are you on, exactly?
good question... multiprocessing-with-queue. Is that the most recent?
in auspex_dummy_mode
, it bails at the same point, but with this error:
Can't pickle <class 'unittest.mock.MagicMock'>: it's not the same object as unittest.mock.MagicMock
Okay, I can duplicate this on macOS if I create subprocesses with spawn
rather than fork
. This doesn't bode well for windows, which can't use the latter. I'll see what can be done — wish I'd seen this coming.
I tried using pathos.multiprocess
which is a fork of multiprocessing
that uses dill
to serialize rather than pickle
, but immediately ran into problems with how it handles Event()
constructors.
Another approach I figured @dellard might weight in on is having two alternative sets of imports that provide either Process
and process-safe Queue
s and Events
or Threads
and thread-safe Queue
s and Events
. This way we're mostly just shuffling imports, since it seems like the APIs are essentially the same.
I thought there was a migration away from Windows underway. Is this not true? (if it isn't true, then I guess I need a way to test things on Windows: which flavor of Windows do I need?)
From what I've read, the issue that most people run into with spawn vs fork is that with the latter, imports are imported once, and with the former, each new Python process is started independently and so the imports are done for each. If we still have code that does stuff at import-time then maybe it's colliding.
Using spawn also requires things to be pickled that aren't pickled in a 'fork'-based multiprocessing world. It makes sense that FileID is something that would be challenging to pickle, but maybe we can work around it: could we just pass the filename around, instead of the FileID?
I don't think we want to completely abandon Windows since we do have some external users, and it would be a shame to completely preclude the possibility.
You're right that the FileID could be fixed, but the larger problem is that our various objects contain references to each other. The question of why an X6 is having problems with a FileID is, I believe, because we pass a Stream
to the X6 driver, which contains a reference to the InputConnector
on a file writer, which contains a reference to the I/O Filter
, which contains the FileID. Python tries to pickle all of this since we were passing the 'stream'.
So we can acquiesce and pass the Queue
directly to avoid this issue, turning the receive_data
method into a @staticmethod
. This approach becomes very difficult in Filter
objects since we've typically perform a lot of initializations that end up as instance variables. We'd have to get rid of a whole mess of self.
references to make things work.
I pushed a fix for this to the head of feature/multiprocessing-with-queue (at c46f93f0d6cff5d29fca7a42f8ecc43e8b99d9a4)
The basic approach, as suggested by @grahamrow, is to load different modules as the same name on different platforms, i.e. on platforms that use fork()
we use multiprocessing
, and on other platforms (or when the user sets the NOFORKING
environment variable) we use threading
, since the interfaces for these are similar enough that we can use either one (as long as we're consistent).
It seems to work, but it needs careful review.
I'm afraid to report a new Windows error...
Exception in thread Thread-17:
Traceback (most recent call last):
File "C:\Users\qlab_user\Anaconda3\envs\pyqt5\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\Users\qlab_user\Anaconda3\envs\pyqt5\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "c:\users\qlab_user\documents\github\auspex\src\auspex\instruments\X6.py", line 275, in receive_data
buf = sock.recv(msg_size, socket.MSG_WAITALL)
OSError: [WinError 10045] The attempted operation is not supported for the type of object referenced
OK; more proof that I need to finish resurrecting my Windows box to do real testing...
The good news is that this particular incompatibility has a known workaround, which I will add.
Writer processes keep running when averagers and plotters are finished.
I'm overhauling the writer to deal with adaptive sweeping, part of which was making the doneness more robust. Will advise.
Okay I've pushed up fixes that have all the unit tests passing on macOS (including adaptive sweeps). I'm going to spin up a virtual machine in order to check the windows side of things.
This appears to be resolved, including in changes of PR #280
Initializing an X6 gives the following error: