Guido van Rossum <[email protected]> writes:
>> Suppose somebody is using asyncio, and we're in the middle of some
>> asyncio coroutine:
>>
>> @asyncio.coroutine
>> def do_stuff(b)
>> #...
>> yield from asyncio.sleep(1)
>> # ...
>> yield from other_fn()
>> # ...
>>
>> Is there something that I could yield in other_fn that will cause it to
>> be resumed once a specific fd is writable?
>>
>
> If other_fn() was a regular function it could return a Future. Or if it was
> an asyncio coroutine (decorated with @asyncio.coroutine) it could yield
> from a Future. However it can't just yield a Future -- that will make a
> boobietrap go off specifically set up to prevent you from making the
> mistake of yielding a Future instead of yielding *from* it.
>
> Then of course you have to arrange for the Future's result to be set when
> your FD is ready. You do that with an I/O callback. I'll explain below.
>
>
>> I'm thinking about something like this:
>>
>> def other_fn():
>> # ...
>> yield asyncio.resume_me_when_writable(some_fd)
>> buf = os.write(some_fd, 42)
>> # ...
>>
>> The add_writer() method of the BaseEventLoop seems related to this, but
>> doesn't quite do what I want. I don't want to register a callback, I
>> want to resume the coroutine..
>>
>
> Yes, you do want to register a write callback that calls f.set_result(None)
> (and the probably removes the write callback.
>
> I think if you study the implementation of sock_sendall() (and
> _sock_sendall()) in asyncio/selector_events.py you'll get my gist;
> sock_sendall() is a function returning a Future that will be made complete
> when the I/O is done; _sock_sendall() first just tries to send (all FDs
> here are nonblocking) and if that fails it registers itself as a write
> callback and then upon being called again it unregisters itself and tries
> to send again (hoping that this time it will not block, otherwise it'll
> just re-register itself and so on).
Ah, I think I have an idea what to do, thanks!
There is one more thing I'm struggling to understand though: if my
callback gets called and marks the future as done, how does the main
event loop know that it can call next() on the future now? Looking at
futures.py, set_result() doesn't seem to do anything than update the
internal state and call any registered callbacks. Is the event-loop
registering callback for itself when it receives a future?
Thanks,
Nikolaus
--
Encrypted emails preferred.
PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C
»Time flies like an arrow, fruit flies like a Banana.«