Hi all,
just to let you know, there is a related issue with UI loops when they
get saturated and you want to keep the UI responsive. I received a pull
request exposing the problem in gbulb last week. The point is that when
the event loop is saturated by asyncio tasks (maybe some background
tasks), the GUI won't be refreshed at all.
https://bitbucket.org/a_ba/gbulb/pull-request/1/set-priority-of-immediate-events-to/diff
(note: I am still thinking about the issue, I am not pushing priorities
into asyncio actually ;)
Anthony
On 27/02/2014 20:49, Kelketek Rritaa wrote:
Urwid has different options for event loops. It offers your choice of
Tornado, Twisted, Glib, a basic Select based loop of its own creation,
and, if I have any say in it, AsyncIO :) It then has a wrapper class
around it. One of the functions is used for scheduling idle tasks.
Glib and Tornado have direct support, the select loop is its own
implementation, so that does, too. In Twisted's case, it's got a bunch
of warnings around it that it's having to hack it in by doing it every
1/x of a second.
I can certainly come up with a set of minimal changes that will do
this for your review. I should be able to have them done by the end of
the day, and if not, sometime tomorrow. :)
On Feb 27, 2014, at 1:43 PM, Guido van Rossum <[email protected]
<mailto:[email protected]>> wrote:
I see. This could be an issue with anything that's an UI event loop.
However, I would assume that in most cases you would take the
existing UI framework's event loop and wrap an asyncio-compatible
interface around it, rather than taking asyncio's event loop and
augmenting it to support the UI. (Most UI frameworks are way too
complex to replicate, so realistically you have no choice.)
It sounds as if things are different for curses, which doesn't really
have its own event loop IIRC. (But does Urwid? I know nothing about it.)
Anyway, I don't want to promise I'll accept a contribution, but I
don't want to reject it unseen either -- can you come up with a
minimal set of changes to asyncio that would implement the feature
you desire? Maybe we can discuss such a patch more easily than I can
understand your Urwid pull request.
On Thu, Feb 27, 2014 at 11:31 AM, Kelketek Rritaa <[email protected]
<mailto:[email protected]>> wrote:
Urwid uses it to refresh the screen. Since curses lets changes
build up until you explicitly call refresh, it's efficient to do
it after all other calls in the loop. But you don't want to call
it after every other single action, and you don't want to call it
just every 1/xth of a second, because it might not always be needed.
However, if something is changing in an Urwid program, and that
causes an AsyncIO task, chances are the screen needs to be
refreshed. So making sure that the screen always refreshes when
there's a task seems like the right way to do it.
The same principle could be applied to anything with a buffer
that needs to be periodically flushed, but should be flushed at a
fixed interval, and not flushed at the end of every single task
if there's going to be a batch of them in one iteration of the loop.
On Feb 27, 2014, at 1:12 PM, Guido van Rossum <[email protected]
<mailto:[email protected]>> wrote:
(Redirecting the discussion back to the list.)
On Thu, Feb 27, 2014 at 10:46 AM, Kelketek Rritaa
<[email protected] <mailto:[email protected]>> wrote:
[...]
But yes. I should certainly give examples on when it might
be useful.
Say you're working with another library. You might know that
the library occasionally does something that changes state,
but you either don't trust that library's code to make that
change easily accessed by an AsyncIO task, or you just find
it easier to read and maintain to add an idle task that
occasionally cleans things up or updates things according to
that other library's work.
Alternatively, you might just have cleanup tasks that need
to do x, y, and z, and adding an extra call to the end of
every task to run the cleanup routine would result in
repeated code that could just be taken care of at the end of
the loop.
Hm... Do you have specific examples of these? In either case it
would seem likely that the idle task could do a lot of extra
work -- it will run whenever the loop is about to go idle,
whether or not there is anything to clean up or update.
--