Hello,
I am having trouble getting async with to work with an arbitrary (and varying) number of asynchronous context managers. Once, contextlib provided nested for this, but apparently they were unable to make it work properly so it was dropped. This led me to Trio… I thought perhaps Trio would be able to manage the context managers if I added them to the Nursery. However, this does not seem to be the case. My original code is:
async with self._clean_targets['test']['gui']['cube'].serve(self.__stop) as cube1, \
self._clean_targets['try_multifield_1']['gui']['cube'].serve( self.__stop ) as cube2, \
websockets.serve( self._pipe['control'].process_messages, self._pipe['control'].address[0], self._pipe['control'].address[1] ) as ctrl, \
websockets.serve( self._clean_targets['test']['converge']['pipe'].process_messages, self._clean_targets['test']['converge']['pipe'].address[0], self._clean_targets['test']['converge']['pipe'].address[1] ) as conv1, \
websockets.serve( self._clean_targets['try_multifield_1']['converge']['pipe'].process_messages, self._clean_targets['try_multifield_1']['converge']['pipe'].address[0], self._clean_targets['try_multifield_1']['converge']['pipe'].address[1] ) as conv2:
self.__result_future = asyncio.Future( )
yield ( self.__result_future, { 'cube1': cube1, 'cube2': cube2, 'conv1': conv1, 'conv2': conv2, 'ctrl': ctrl } )
'try_multifield_1' and 'test' are just a hard-coded single use case, the actual number of instances would be determined at runtime.
I believe websocket.serve(...) is returning an asynchronous context manager. The process_message functions are async functions which respond to messages sent from the external process (browser with Bokeh display). I hoped that I would be able to use Trio like:
async with trio.open_nursery( ) as ns:
ns.start_soon( self._clean_targets['test']['gui']['cube'].serve(self.__stop) )
ns.start_soon( self._clean_targets['try_multifield_1']['gui']['cube'].serve( self.__stop ) )
ns.start_soon( websockets.serve( self._pipe['control'].process_messages, self._pipe['control'].address[0], self._pipe['control'].address[1] ) )
ns.start_soon( websockets.serve( self._clean_targets['test']['converge']['pipe'].process_messages, self._clean_targets['test']['converge']['pipe'].address[0], self._clean_targets['test']['converge']['pipe'].address[1] ) )
ns.start_soon( websockets.serve( self._clean_targets['try_multifield_1']['converge']['pipe'].process_messages, self._clean_targets['try_multifield_1']['converge']['pipe'].address[0], self._clean_targets['try_multifield_1']['converge']['pipe'].address[1] ) )
self.__result_future = asyncio.Future( )
await self.__result_future
Is there a way to use a Trio nursery to run and clean up these asynchronous context managers (along with the async functions)? I assume that there is not since maybe this is outside of Trio’s wheelhouse… anyway, I’m definitely not an asyncio expert so I would really appreaciate any advice. Thanks in advance…