Despite my concerns over code for an implementation on my previous e-mail, it turns out that simply iterating in an `async for` loop won't yield to the asyncio-loop. An explicit "await" inside the async-generator is needed for that.
That makes factoring-out the code presented in the first e-mail in this thread somewhat trivial - and it will read something like: ``` async def switch(): await asyncio.sleep(0) async def iterate_non_blocking(iterator, timeout=None, iterations=None): if timeout is None and iterations is None: timeout = 0.1 ts = time.time() counter = 0 for item in iterator: yield item counter += 1 if iterations and (counter >= iterations) or timeout and time.time() - ts >= timeout: await switch() counter = 0 ts = time.time() ``` Which can then be used like: ``` async for i in iterate_non_blocking(range(steps), iterations=30): ... ``` I've created a gist with this code at https://gist.github.com/jsbueno/ae6001c55ee3ff001fb7c152b1f109b2 And if people agree it is imporant enough, I am ok with creating a full-package with this code, or help adding it to the stdlib. On Fri, 14 Jun 2019 at 11:58, Joao S. O. Bueno <jsbu...@python.org.br> wrote: > So - > > Now thinking on the problem as a whole - > I think maybe a good way to address this is to put the logic on > "counting N interations or X time and allowing switch" - the logic you > had to explicitly mingle in your code in the first example, in > a function that could wrap the iterator of the `for` loop. > > However, that idea would need a _synchronous_ call to the loop > to force an async context switch - I don't know if > there is such a call (even an internal one). Actually > I don't know it that is possible - but I can't think of other way of > factoring it out without explicitly triggering an await. > > The switcher would then be used just as we use `enumerate` - > think of something along: > > > for context_switch, data_set in async_switcher(data_sets, timeout=100): > for record in context_switch(data_set): > # the call to __iter__ here would include the logic to decide > whether to switch, > ... > > And for a single (non-nested) loop, either a separate call or: > > for data_set in next(async_switcher(data_sets, timeout=100))[0]: > ... > > All in all: if there is a valid way to force the async-context switch in > an > sync-call to this wrapper object, it is possible to create a small package > that would have this feature and be easy to use. > (And then, we discuss further down if this is stdlib worthy) > > > > > > On Fri, 14 Jun 2019 at 09:45, Nikita Melentev <multisosnoo...@gmail.com> > wrote: > >> The problem here is that even if I have a coroutine all code between >> «awaits» is blocking. >> >> ``` python >> async def foo(): >> data = await connection.get() # it is ok, loop handling request, we >> waiting >> # from here >> for item in data: # this is 10 ** 6 len >> do_sync_jon(item) # this took 1ms >> # to here we are blocking loop for 1 second >> await something_next() >> ``` >> _______________________________________________ >> Python-ideas mailing list -- python-ideas@python.org >> To unsubscribe send an email to python-ideas-le...@python.org >> https://mail.python.org/mailman3/lists/python-ideas.python.org/ >> Message archived at >> https://mail.python.org/archives/list/python-ideas@python.org/message/BLLU545Y2FLACLMHC6OVXGJ5YUF66E4K/ >> Code of Conduct: http://python.org/psf/codeofconduct/ >> >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/EYDG5HHRM2GC3O67IRTWDXVDAWD4YIKB/ Code of Conduct: http://python.org/psf/codeofconduct/