7

I'm very new to asyncio and was wondering which API is better than the other in terms of better practice, protocol or streams?

To me, protocol(callback based API) seems easier to work with since there are already connection_made and data_received methods provided to you. With streams(coroutine based API) you have to manage connections and read data yourself, but I feel like it utilizes concept of coroutine more, which seems a good thing to me.

this is how i listen to incoming data, feels awkward to me. I can also use readeexactly but sometimes it raises IncompleteReadError.

message_body = b''
message_length = SOME_NUMBER
while True:
    while len(message_body) < message_length:
        try:
            message_body_chunk = await reader.read(message_length - len(message_body))
        except Exception as e:
            self.logger.error(e)
            return
            if not message_body_chunk:
                return
            message_body += message_body_chunk
shangsunset
  • 1,585
  • 4
  • 22
  • 38

1 Answers1

6

The stream objects are higher level and provide many useful methods:

Like any abstraction, this comes at a cost: coroutine are a bit less reactive than callbacks. For instance reader.read() involves at least two event loop callbacks:

  • When some data is received, a callback is triggered and reader.feed_data is called.
  • Then feed_data triggers another callback that restores the execution of reader.read().
Vincent
  • 12,919
  • 1
  • 42
  • 64
  • 1
    Also, an important point to note is that asyncio does not ensure that data_received in Protocol is always called with entire data. You may need to do your own buffer-management if the amount of data is large, or increase the buffer limit. – Zack May 04 '18 at 20:38
  • 1
    @Zack This doesn't have much to do with asyncio, but rather TCP itself. TCP is [stream oriented](https://stackoverflow.com/a/17446839/2846140), so there is no such thing as the "entire data". It's up to the application layer to define a protocol with its own concept of packet (e.g. fixed length, ending with a specific separator, etc.). This is why the asyncio stream reader provides the readuntil and readexactly helpers. – Vincent May 09 '18 at 14:09