After merge the new develop branch of
aiida_core and new develop
plumpy the previous problem that when closing
the communicator, the program hangs without respond is no longer show up again.
I can not reproduce the exception, so just ignore the question for the time being.
But since the starting of using
LoopCommunicator as communicator, there are more problems bubble up to the desktop.
Issue 1: using
asyncio.Future is used with associated loop, it can not be await in the other loop.
It is not hard to just fix it if we need the Process initiated with
by specifying the loop:
@persistence.auto_persist('_pid', '_creation_time', '_future', '_paused', '_status', '_pre_paused_status') class Process(StateMachine, persistence.Savable, metaclass=ProcessStateMachineMeta): ... def __init__(self, inputs=None, pid=None, logger=None, loop=None, communicator=None): ... # Runtime variables self._future = persistence.SavableFuture(loop=self._loop) ...
However, when recreating the
SavableFuture from saved, the loop is supposed to be
designated. Otherwise will get the exception ‘RuntimeError: Non-thread-safe operation invoked on an event loop other than the current one’
Does loop need to be stored as the persister or just passed as context of
If the loop in the
load_context is desired, how to save and load it explicitly?
Issue 2: callback in
call_on_process_finish can be any callable
LoopCommunicator is used as the communicator now, all communications over RabbitMQ
will go through
create_task plumpy expect a coroutine to be
scheduled in the event loop, but it always not the case, the callback passed to the
method can be any callable functions coroutines, regular functions,
or even classes with
__call__ method. That is to say, a way to ensure the coroutine is needed.
By google it, find in asyncio programming, it is encourage to explicitly distinguish the coroutine and regular functions.
async def async_gettter(): return (await http_client.get("http://example.com")) def sync_getter(): return asyncio.get_event_loop().run_until_complete(async_getter())
But not easily to convert to a coroutine with deep function calls.
inline_callback wrap the
callback, if callback is not a coroutine,
we need first convert it to the coroutine and await it in the
inline_callback and then
inline_callback into a coroutine either.
The question is when porting to code to asyncio, do I need to make sure all the callbacks
passed to the
create_task is coroutine, even if it not did any network/IO operations?