Python Forum

Full Version: asyncio: run_until_complete() returns when the first of gathered Futures is set
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i have the following code:
import asyncio
import functools

class EchoClientProtocol(asyncio.Protocol):
    def __init__(self, message, future):
        self.message = message
        self.f = future

    def connection_made(self, transport):
        self.transport = transport
        transport.write(self.message.encode())
        print('Data sent: {!r}'.format(self.message))

    def data_received(self, data):
        print('Data received: {}'.format(data.decode('utf-8')))
        self.transport.close()
        self.f.set_result(True)

    def connection_lost(self, exc):
        print('Connection lost')


loop = asyncio.get_event_loop()
message = "hello"
connectionsTasks = []
dataReceivedTasks = []

for i in range(5):
    dataReceivedFuture = asyncio.Future()
    connectionFuture = loop.create_connection(lambda: EchoClientProtocol(message, dataReceivedFuture),
                               '127.0.0.1', 2222)
    connectionsTasks.append(connectionFuture)
    dataReceivedTasks.append(dataReceivedFuture)

connectionFutures = asyncio.gather(*connectionsTasks)
dataReceivedFutures = asyncio.gather(*dataReceivedTasks)
loop.run_until_complete(connectionFutures)
loop.run_until_complete(dataReceivedFutures)
loop.close()
What i want is create concurrently 5 connections as client, send data, get responses and when all of them have arrived exit the asyncio loop. In the loop creating the connections i create new futures that i pass as argument and set when i have received back data. Then store them in a list and through the gather() function i create a future that is set when all of them are set. But when i run the code and get the second response i get a "asyncio.base_futures.InvalidStateError: invalid state" error on line 17 (self.f.set_result(True)) which tells me actually that i have already set the future. Shouldn't it be a diffrent future than the previous? How can i achieve the result i'm trying?