Closed bernardnormier closed 3 years ago
If you merge this into 3.7 don't forget to cherry-pick to 3.7.5-rc too, or just update the PR to merge in 3.7.5-rc
Should we consider using a dispatch instead of
wrap_future
? Futures returned by Ice async calls would get completed through the dispatcher which would callloop.call_soon_threadsafe
to ensure that the continuation of the future is ran on event loop.We could also consider adding a loop parameter to the communicator initialization (if set this would setup a dispatcher to run calls on the loop).
Your comment is not clear to me.
If you merge this into 3.7 don't forget to cherry-pick to 3.7.5-rc too, or just update the PR to merge in 3.7.5-rc
Merged to 3.7.5-rc.
My idea was to do the same as the C# async demo... something along these lines:
async def main():
# Ice.initialize returns an initialized Ice communicator; the communicator is destroyed once it goes out of scope.
with Ice.initialize(sys.argv, "config.client") as communicator:
# The communicator initialization removes all Ice-related arguments from sys.argv
if len(sys.argv) > 1:
print(sys.argv[0] + ": too many arguments")
return 1
try:
hello = Demo.HelloPrx.uncheckedCast(communicator.propertyToProxy('Hello.Proxy'))
except Ice.Exception as ex:
print("invalid proxy:", ex)
return 1
menu()
while True:
sys.stdout.write("==> ")
sys.stdout.flush()
c = await asyncio.get_event_loop().run_in_executor(None, sys.stdin.readline)
c = c.strip()
if c == 'i':
await Ice.wrap_future(hello.sayHelloAsync(0))
elif c == 'd':
asyncio.create_task(slowSayHello(hello))
elif c == 's':
await Ice.wrap_future(hello.shutdownAsync())
elif c == 'x':
return 0
elif c == '?':
menu()
else:
print(f"unknown command {c!r}")
menu()
async def slowSayHello(hello):
try:
await Ice.wrap_future(hello.sayHelloAsync(5000))
print("slow hello completed")
except Ice.Exception as ex:
print("task exception:", ex)
except RuntimeError as ex:
print("task runtime error:", ex)
While sayHelloAsync(0)
and shutdown()
won't run in parallel, I don't think that's a big deal, the demo is a lot simpler like this.
Another step could be to get rid of the Ice.wrap_future
calls by using a dispatcher that ensures that AMI continuations are ran from the event loop. I tried this but for some reasons it doesn't work, I'm getting a RuntimeError: Task got bad yield: <Ice.InvocationFuture object at 0x10a374fd0>
from the yield in IceFuture.__await__
(defined in IceFuture.py
).
This PR simplifies the async and asyncInvocation demos by switching to await and asyncio.