<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    09.08.2015, 03:22, Nick Coghlan kirjoitti:<br>
    <blockquote
cite="mid:CADiSq7fxq+hwt5hg+8oNF93So3Shet_SY43pPJoFZH91AWbSjg@mail.gmail.com"
      type="cite">
      <p dir="ltr"><br>
        On 8 Aug 2015 22:48, "Alex Grönholm" <<a
          moz-do-not-send="true" href="mailto:alex.gronholm@nextday.fi">alex.gronholm@nextday.fi</a>>

        wrote:<br>
        ><br>
        > That name would and argument placement would be better, but
        are you suggesting that the ability to pass along extra
        arguments should be removed? The original method was bad enough
        in that it only supported positional and not keyword arguments,
        forcing users to pass partial() objects as callables.</p>
      <p dir="ltr">That's a deliberate design decision in many of
        asyncio's APIs to improve the introspection capabilities and to
        clearly separate concerns between "interacting with the event
        loop" and "the operation being dispatched for execution".</p>
    </blockquote>
    While I won't pretend to understand what this means, I recognize
    that you've given it considerably more thought than I have.<br>
    <blockquote
cite="mid:CADiSq7fxq+hwt5hg+8oNF93So3Shet_SY43pPJoFZH91AWbSjg@mail.gmail.com"
      type="cite">
      <p dir="ltr">>> With the suggested change to the method name
        and signature, the same<br>
        >> example would instead look like:<br>
        >><br>
        >>      async def handler(self):<br>
        >>          loop = asyncio.get_event_loop()<br>
        >>          result = await<br>
        >>
        loop.call_in_background(some_blocking_api.some_blocking_call)<br>
        >>          await self.write(result)<br>
        ><br>
        > Am I the only one who's bothered by the fact that you have
        to get a reference to the event loop first?<br>
        > Wouldn't this be better:<br>
        ><br>
        > async def handler(self):<br>
        ><br>
        >     result = await
        asyncio.call_in_background(some_blocking_api.some_blocking_call)<br>
        ><br>
        >     await self.write(result)</p>
      <p dir="ltr">That was my original suggestion a few weeks ago, but
        after playing with it for a while, I came to agree with Guido
        that hiding the event loop in this case likely wasn't helpful to
        the conceptual learning process. Outside higher level frameworks
        that place more constraints on your code, you really can't get
        very far with asyncio without becoming comfortable with
        interacting with the event loop directly.</p>
    </blockquote>
    As long as I can still write a high level framework where
    boilerplate is minimized in user code, I can "yield" on this issue.<br>
    <blockquote
cite="mid:CADiSq7fxq+hwt5hg+8oNF93So3Shet_SY43pPJoFZH91AWbSjg@mail.gmail.com"
      type="cite">
      <p dir="ltr">I gave a demo using the current spelling as a
        lightning talk at PyCon Australia last weekend:<br>
        <a moz-do-not-send="true"
          href="https://www.youtube.com/watch?v=_pfJZfdwkgI">https://www.youtube.com/watch?v=_pfJZfdwkgI</a></p>
      <p dir="ltr">The only part of that demo I really wasn't happy with
        was the "run_in_executor" call - the rest all felt good for the
        level asyncio operates at, while still allowing higher level
        third party APIs that hide more of the underlying machinery
        (like the event loop itself, as well as the use of partial
        function application).<br>
        ><br>
        ><br>
        > The call_in_background() function would return an awaitable
        object that is recognized by the asyncio Task class, which would
        then submit the function to the default executor of the event
        loop.<br>
        ><br>
        >> That should make sense to anyone reading the handler,
        even if they<br>
        >> know nothing about concurrent.futures - the precise
        mechanics of how<br>
        >> the event loop goes about handing off the call to a
        background thread<br>
        >> or process is something they can explore later, they
        don't need to<br>
        >> know about it in order to locally reason about this
        specific handler.<br>
        >><br>
        >> It also means that event loops would be free to
        implement their<br>
        >> *default* background call functionality using something
        other than<br>
        >> concurrent.futures, and only switch to the latter if an
        executor was<br>
        >> specified explicitly.<br>
        ><br>
        > Do you mean background calls that don't return objects
        compatible with concurrent.futures.Futures?</p>
      <p dir="ltr">A background call already returns an asyncio
        awaitable, not a concurrent.futures.Future object.</p>
      <p dir="ltr">> Can you think of a use case for this?</p>
      <p dir="ltr">Yes, third party event loops like Twisted may have
        their own background call mechanism that they'd prefer to use by
        default, rather than the concurrent.futures model.</p>
    </blockquote>
    What I don't get is why you say that this name and signature change
    would somehow enable event loops to implement an alternative
    mechanism for background calls. By event loops do you mean something
    like Twisted's reactors or just customized versions of asyncio event
    loops? To me, the former makes no sense at all and with the latter,
    I don't see how this name and signature change changes anything.
    Could they not already use whatever mechanism they please as long as
    it returns an awaitable (or iterable in the case of 3.4 or earlier)
    object, by having their custom implementation of run_in_executor()?<br>
    <blockquote
cite="mid:CADiSq7fxq+hwt5hg+8oNF93So3Shet_SY43pPJoFZH91AWbSjg@mail.gmail.com"
      type="cite">
      <p dir="ltr">>> There are still some open questions about
        whether it makes sense to<br>
        >> allow callables to indicate whether or not they expect
        to be IO bound<br>
        >> or CPU bound,<br>
        ><br>
        > What do you mean by this?</p>
      <p dir="ltr">There was a thread on the idea recently, but I don't
        have a link handy. Indicating CPU vs IO bound directly wouldn't
        work (that's context dependent), but allowing callables to
        explicitly indicate "recommended", "supported", "incompatible"
        for process pools could be interesting.</p>
    </blockquote>
    Yeah -- it'll be interesting to see where that goes.<br>
    <blockquote
cite="mid:CADiSq7fxq+hwt5hg+8oNF93So3Shet_SY43pPJoFZH91AWbSjg@mail.gmail.com"
      type="cite">
      <p dir="ltr">>>   and hence allow event loop implementations
        to opt to<br>
        >> dispatch the latter to a process pool by default<br>
        ><br>
        > Bad idea! The semantics are too different and process pools
        have too many limitations.</p>
      <p dir="ltr">Yes, that's why I find it an intriguing notion to
        allow callables to explicitly indicate whether or not they're
        compatible with them.</p>
      <p dir="ltr">Cheers,<br>
        Nick </p>
    </blockquote>
    <br>
  </body>
</html>