On Sun, Jun 25, 2017 at 10:46 PM, Yarko Tymciurak <yarkot1@gmail.com> wrote:


On Sun, Jun 25, 2017 at 10:33 PM, Guido van Rossum <gvanrossum@gmail.com> wrote:
On Sun, Jun 25, 2017 at 3:38 PM, Yarko Tymciurak <yarkot1@gmail.com> wrote:
To be a well-behaved (capable of effective cooperation) task in such a system, you should guard against getting embroiled in potentially blocking I/O tasks whose latency you are not able to control (within facilities available in a cooperative multitasking context).  The raises a couple of questions: to be well-behaved, simple control flow is desireable (i.e. not nested layers of yields, except perhaps for a pipeline case); and "read/write" control from memory space w/in the process (since external I/O is generally not for async) begs the question: what for?  Eliminate globals, encapsulate and limit access as needed through usual programming methods.

Before anyone takes this paragraph too seriously, there seem to be a bunch of misunderstandings underlying this paragraph.

yes - thanks for the clarifications...  I'm speaking from the perspective of an ECE, and thinking in the small-scale (embedded) of things like when in general is cooperative multitasking (very light-weight) more performant than pre-emptive... so from that space: 

- *All* blocking I/O is wrong in an async task, regardless of whether you can control its latency. (The only safe way to do I/O is using a primitive that works with `await`.)

yes, and from ECE perspective the only I/O is "local" device (e.g. RAM, which itself has rather deterministic setup and write times...), etc.

my more general point (sorry - should have made it explicit) is that if you call a library routine, you may not expect it's calling external I/O, so that requires either care (or defensively guarding against it, e.g. with timers ... another story).   This in particular is an error which I saw in OpenStack swift project - they depended on fast local storage device I/O.  Except when devices started failing.   Then they mistakenly assumed this was python's fault - missing the programming error of doing async (gevent - but same issue) I/O (which might be ok, within limits, but was not guarded against - was done in an unreliable way).

So - whether intentionally doing such "risky" but seemingly reliable and "ok" I/O and failing to put in place guards, as must be in cooperative multitasking, or if you just get surprised that some library you thought was inoccuous is somewhere doing some surprise I/O (logging? anything...).... in cooperative multi-tasking, you can get away with some things, but it is _all_ your responsibility to guard against problems.

That was my point here.


- There's nothing wrong with `yield` itself. (You shouldn't do I/O in a generator used in an async task -- but that's just due to the general ban on I/O.)

Yes;  as above.  But I'm calling local variables (strictly speaking) I/O too.   And you might consider REDIS as "to RAM, so how different is that?" --- well, it's through another process, and ... up to a preemptive scheduler, and all sorts of things.  So, sure - you _can_ do it, if you put in guards.  But don't.  Or at least, have very specific good reasons, and understand the coding cost of trying to do so.  In other words - don't.
 

- Using async tasks don't make globals more risky than regular code (in fact they are safer here than in traditional multi-threaded code).

- What on earth is "read/write" control from memory space w/in the process?

Sorry - these last two were a bit of a joke on my part.   The silly:  only valid I/O is to variables.  But you don't need that, because you have normal variable scoping/encapsulation rules.   So (I suppose my joke continued), the only reason to have "read/write controls left is against (!) global variables.  Answer - don't;  and you don'' need R/W controls, because you have normal encapsulation controls of variables from the language.  So - in cooperative multitasking, my argument goes, there can be (!) no reasonable motivation for R/W controls.

-- Yarko
 


--
--Guido van Rossum (python.org/~guido)