> On 04 Oct 2016, at 18:15, Guido van Rossum <gu...@python.org> wrote: > > On Tue, Oct 4, 2016 at 4:30 AM, Nick Coghlan <ncogh...@gmail.com> wrote: >> class SomeClass(object): >> def some_sync_method(self): >> return 42 >> async def some_async_method(self): >> await asyncio.sleep(3) >> return 42 >> >> o = auto_schedule(SomeClass()) # Indicating that the user wants an >> async version of the object >> r1 = o.some_sync_method() # Automatically run in a background thread >> r2 = o.some_async_method() # Automatically scheduled as a coroutine >> print(run_in_foreground(r1)) >> print(run_in_foreground(r2)) > > So maybe r1 and r2 are just concurrent.futures.Futures, and > run_in_foreground(r) wraps r.result(). And auto_schedule() is a proxy > that turns all method calls into async calls with a (concurrent) > Future to wait for the result. There's an event loop somewhere that > sits idle except when you call run_in_foreground() on somethong; it's > only used for the async methods, since the sync methods run in a > background thread (pool, I hope). Or perhaps r2 is an asyncio.Future > and run_in_foreground(r2) wraps loop.run_until_complete(r2). I suppose > the event loop should also be activated when waiting for r1, so maybe > r1 should be an asyncio Future that wraps a concurrent Future (using > asyncio.wrap_future(), which can do just that thing). > > Honestly it feels like many things can go wrong with this API model, > esp. you haven't answered what should happen when a method of > SomeClass (either a synchronous one or an async one) calls > run_in_foreground() on something -- or, more likely, calls some > harmless-looking function that calls another harmless-looking function > that calls run_in_foreground(). At that point you have pre-emptive > scheduling back in play (or your coroutines may be blocked > unnecessarily) and I think you have nothing except a more complicated > API to work with threads.
I am a little out on deep water here, but I think that if an object instance was guaranteed - by Python runtime - to run in one coroutine/thread and only the message passing of method call and return values was allowed to pass between coroutine/thread context, then at least all local instance variable reference would be fine? > I think I am ready to offer a counterproposal where the event loop > runs in one thread and synchronous code runs in another thread and we > give the synchronous code a way to synchronously await a coroutine or > an asyncio.Future. This can be based on > asyncio.run_coroutine_threadsafe(), which takes a coroutine or an > asyncio.Future and returns a concurrent Future. (It also takes a loop, > and it assumes that loop runs in a different thread. I think it should > assert that.) > > The main feature of my counterproposal as I see it is that async code > should not call back into synchronous code, IOW once you are writing > coroutines, you have to use the coroutine API for everything you do. > And if something doesn't have a coroutine API, you run it in a > background thread using loop.run_in_executor(). > > So either you buy into the async way of living and it's coroutines all > the way down from there, no looking back -- or you stay on the safe > side of the fence, and you interact with coroutines only using a very > limited "remote manipulator" API. The two don't mix any better than > that. Maybe not, but I am hoping for something better :-) > > -- > --Guido van Rossum (python.org/~guido) > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/