1
resposta

Como escrever um wait_for?

Meu caso especifico é com asyncssh, mas acho que seria um pattern para todos de forma genérica. Quanto eu envio dados para uma conexão uso um objeto channel. A resposta vem no objeto session em uma função que sobrescrevo. Só que o terminal que uso não envia nenhum evento dizendo que acabou de enviar dados. Ou seja eu tenho que esperar com um sleep, meio porco mas é o que me resolve hoje, eu queria mudar isso para analisar o conteúdo recebido a cada momento que ele é recebido.

    def data_received(self, data, datatype):
        print(data)
        _buffer += data
        #notificar quem esta esperando continuar. COMO???
   async def wait_for(self, info_desejada, delay):
        start_time_wait_for = time.time()
        while True:
            if (info_desejada in _buffer)
                    or ((time.time() - start_time_get_ont) > delay):
                return _buffer
            await asyncio.sleep(1)
            #esperar até algum dado ser recebido ou delay segundos COMO???
channel.write("commando que demora")
retorno = await session.wait_for("prompt", 20)
1 resposta

Oi José, tudo bem? Sinto muito que tenha esperado tanto, não sou nenhum especialista Python, mas vamos lá.

Este é um exemplo onde você deseja digitar algo no terminal, capturar e enviar o dado pelo ssh? Algo nessa linha? Não sei se entendi bem.

Pensando de forma mais abstrata, os terminais, quando você digita algo e pressiona enter para executar o comando, o final da string vem com um \n, então você pode usar isso como gatilho para executar algo se a string termina com o \n.

Neste caso, seu loop pode ficar infinito e a pausa pode ser por time-out (depois de tantos segundos, se nada foi executado, fecha a conexão) ou por palavra chave (exit, por exemplo).

Pensando em padrões, você pode até mesmo aplicar um strategy para executar ações diferentes de acordo com a combinação que entrar no terminal.

Sobre como notificar quem está esperando, a biblioteca deve fornecer alguma função para isso, pelo padrão de nomenclatura das funções, se tem um data_received deve haver alguma outra função que faça a notificação de que o processamento do dado já foi executado.

Eu notei olhando por cima que a biblioteca trabalha com um padrão de Event Loop, então, deve ter algum mecanismo onde você pode emitir um evento notificando justamente o que dejesa notificar, claro, com alguma palavra chave específica da biblioteca.

Pelo padrão do Event Loop, várias ações são executadas por meio de callbacks como você mesmo descreveu. Então, algo que pode ajudar é estudar o fluxo dos eventos e trabalhar em cima disso. O data_received é executado quando você recebe dados, e o eof_received é executado quando o fluxo de dados é finalizado.

Dessa forma, entendo que a própria biblioteca já sabe quando o fluxo de dados finaliza e chama o próximo método da sequência que é esse eof_received onde talvez você já possa executar alguma ação de listening novamente.

A biblioteca também tem classes de Listening, que permite você ficar ouvindo um host por dados e agir em cima disso.

Em fim, espero ter ajudado, desculpa se por acaso deixei as coisas ainda mais confusas, qualquer coisa, fala aqui no tópico que eu tento explorar mais com você o assunto, se achar que faz sentido.

Bons estudos, abraço!