0

TLDR; I want to not immediately return from connection_made function within asyncio.Protocol as i want to implement some time taking checks that should ideally be awaited on within the connection_made function and run transport.abort() right within the function if the checks fail.

I don't know if asyncio.Protocol implementing its handler functions as synchronous functions is a flaw or not.

I've been trying to make changes to a codebase that we have that implements the asyncio.Protocol , and have been experiencing some difficulties in understanding that i won't be able to await on functions inside the non async def connection_made(transport) function.

eg:

import asyncio
import time

def check(peername):
    time.sleep(10)  # await asyncio.sleep(10)
    return False # or True

class EchoServerProtocol(asyncio.Protocol):
    def connection_made(self, transport):
        peername = transport.get_extra_info('peername')
        print('Connection from {}'.format(peername))
        if not  check(peername):
            transport.abort()
            return
        self.transport = transport

    def data_received(self, data):
        message = data.decode()
        print('Data received: {!r}'.format(message))

        print('Send: {!r}'.format(message))
        self.transport.write(data)

        print('Close the client socket')
        self.transport.close()

What I would like to do is to make the check(peer) function an asynchronous method and then await on it so that other connections can be made simultaneously while the check function is still running in the event loop (as it is doing an io operation, not a cpu calculation).

I don't want to return from connection_made without confirming the genuineness of the connection as that could potentially allow the clients to send data when i still haven't verified if the connection is genuine.

I know that i can make check as an async function and call it within asyncio.ensure_future, but that would mean that i would be returning from the connection_made function without the proper checks.

My main reason for wanting to do this is because i have observed that the loop.create_server will not accept any other connections if the previous connection_made has been blocked.

Let me know if using ensure_future is the only way to go while returning from the connection_made function. Or if there is a way to handle IO blocking calls in connection_made without it preventing other connections from being made.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • The answers to [this question](https://stackoverflow.com/questions/20746619/calling-coroutines-in-asyncio-protocol-data-received) may be useful. – larsks Jun 02 '23 at 12:07
  • I advance to you that the sync design is 'a flaw'. Protocols are part of what make higher level async possible - but at this level, there are only callbacks. – jsbueno Jun 02 '23 at 13:36
  • I wint down checking the code inside asyncio which calls `connection_made` itself, and I have bad news. Do you have the control over the transport code? It is not feasible _at_all_ to return control to the asyncio loop from inside "connection_made" - it schedules the "habilitation" of the underlying transport in a sync way just after it is called. – jsbueno Jun 02 '23 at 14:15
  • 1
    But if your transport features "pause_reading" and "resume_reading" - maybe there is some workaround to make the connection checks in an async way, – jsbueno Jun 02 '23 at 14:16
  • I do have control over the transport code. However, i guess doing the pause_reading and resume_reading would make the code too complicated and might introduce unintented bugs as this kind of stuff is ideally supposed to be handled by the library. I suppose i will need to live with the possiblility of processing data received in a delayed manner once i have verified the genuineness of the connection. It can be done by passing off all data that has been received into a future and the async funture will then wait for the verification to complete with a flag or something. – Anirudh Panchangam Jun 04 '23 at 08:18
  • @jsbueno I ended up having to use pause_reading and resume_reading in order to prevent any other data being sent over the connection before we'd verified it. Thanks! – Anirudh Panchangam Jul 28 '23 at 10:37

0 Answers0